From 10f8fe7c08de7766604599b80412417e397810aa Mon Sep 17 00:00:00 2001 From: hyeokjun32 Date: Fri, 12 Jun 2026 00:07:11 +0900 Subject: [PATCH] Track optional AIGuard handoff evidence --- .../runtime_intelligence_gitlab_artifacts.md | 4 ++ .../edgeenv_runtime_regression_lab_handoff.md | 5 ++ .../edgeenv_lab_handoff_manifest.json | 4 ++ ...ck_runtime_intelligence_bundle_manifest.py | 64 +++++++++++++++++++ ...check_runtime_intelligence_ci_artifacts.py | 1 + ...st_runtime_intelligence_bundle_manifest.py | 33 ++++++++++ .../test_runtime_intelligence_ci_template.py | 3 + .../test_runtime_intelligence_smoke_script.py | 1 + 8 files changed, 115 insertions(+) diff --git a/docs/ci/runtime_intelligence_gitlab_artifacts.md b/docs/ci/runtime_intelligence_gitlab_artifacts.md index 566a087..b0c3327 100644 --- a/docs/ci/runtime_intelligence_gitlab_artifacts.md +++ b/docs/ci/runtime_intelligence_gitlab_artifacts.md @@ -140,6 +140,10 @@ The initial gate is conservative: - the same handoff must declare `external_aiguard_required_evidence_types`, and the bundle gate verifies those requirements against the bundled `guard_analysis.evidence` type set +- if the handoff declares `optional_aiguard_evidence_types`, the bundle gate + validates the known stale-drop labels (`stale_frame_risk` and + `edgeenv_orchestrator_stale_drop_summary`) as optional context that remains + separate from the required AIGuard evidence set - the EdgeEnv handoff `runtime_telemetry_history` file must exist and preserve the EdgeEnv history schema, telemetry coverage summary, and Runtime history seed ownership markers diff --git a/docs/portfolio/edgeenv_runtime_regression_lab_handoff.md b/docs/portfolio/edgeenv_runtime_regression_lab_handoff.md index 0ad284f..ccf7496 100644 --- a/docs/portfolio/edgeenv_runtime_regression_lab_handoff.md +++ b/docs/portfolio/edgeenv_runtime_regression_lab_handoff.md @@ -147,6 +147,11 @@ This second smoke uses committed lightweight artifacts to represent the cross-re - `examples/runtime_intelligence_chain/bundle_manifest.json` declares the local-first artifact bundle, file paths, source repositories, artifact roles, producer contracts, owners, and boundary flags. - `examples/runtime_intelligence_chain/edgeenv_lab_handoff_manifest.json` mirrors the EdgeEnv producer-side handoff manifest and its `lab_bundle_alignment` metadata, so Lab can verify EdgeEnv-produced file keys separately from external AIGuard evidence. - The same handoff declares `external_aiguard_required_evidence_types`; Lab's bundle gate checks that those types are present in the external `guard_analysis.evidence` list without making AIGuard the final decision owner. +- If the handoff also declares `optional_aiguard_evidence_types`, Lab validates + the known optional stale-drop evidence labels (`stale_frame_risk` and + `edgeenv_orchestrator_stale_drop_summary`) as optional context only. Those + labels must remain separate from the required Guard evidence set and do not + become a Lab deployment-decision requirement. - `examples/runtime_intelligence_chain/runtime_telemetry_history.json` is the EdgeEnv producer-side telemetry history artifact referenced by the handoff manifest. It includes a missing-telemetry run as an evidence gap and preserves Orchestrator context on that entry without turning Orchestrator into a regression or deployment decision owner. - Orchestrator context is preserved inside the EdgeEnv regression artifact as `orchestrator_operation_context`. - AIGuard deterministic queue/thermal and task-event rollup evidence is passed as a precomputed `guard_analysis` artifact that mirrors the AIGuard producer-side diagnosis v1 evidence shape. diff --git a/examples/runtime_intelligence_chain/edgeenv_lab_handoff_manifest.json b/examples/runtime_intelligence_chain/edgeenv_lab_handoff_manifest.json index 32c40ed..becbd98 100644 --- a/examples/runtime_intelligence_chain/edgeenv_lab_handoff_manifest.json +++ b/examples/runtime_intelligence_chain/edgeenv_lab_handoff_manifest.json @@ -68,6 +68,10 @@ "runtime_thermal_instability", "remote_execution_recovered_by_fallback" ], + "optional_aiguard_evidence_types": [ + "stale_frame_risk", + "edgeenv_orchestrator_stale_drop_summary" + ], "expected_report_markers": [ "Runtime Intelligence Risk Summary", "Runtime replay duration scope", diff --git a/scripts/check_runtime_intelligence_bundle_manifest.py b/scripts/check_runtime_intelligence_bundle_manifest.py index 2ad3299..e753eb4 100644 --- a/scripts/check_runtime_intelligence_bundle_manifest.py +++ b/scripts/check_runtime_intelligence_bundle_manifest.py @@ -105,6 +105,10 @@ "runtime_thermal_instability", "remote_execution_recovered_by_fallback", } +OPTIONAL_AIGUARD_EVIDENCE_TYPES = { + "stale_frame_risk", + "edgeenv_orchestrator_stale_drop_summary", +} REQUIRED_GUARD_EVIDENCE_FIELDS = { "type", "metric_name", @@ -198,6 +202,9 @@ "edgeenv_handoff: missing_telemetry_orchestrator_context validated", "edgeenv_handoff: external AIGuard evidence requirements declared", ) +EDGEENV_HANDOFF_OPTIONAL_AIGUARD_SUMMARY_MARKER = ( + "edgeenv_handoff: optional AIGuard evidence types declared" +) def _load_json(path: Path, label: str) -> dict[str, Any]: @@ -442,6 +449,42 @@ def _validate_edgeenv_handoff_alignment( "AIGuard evidence types", ) + optional_aiguard_evidence_types = alignment.get("optional_aiguard_evidence_types") + if optional_aiguard_evidence_types is not None: + _record( + isinstance(optional_aiguard_evidence_types, list), + errors, + "EdgeEnv handoff lab_bundle_alignment." + "optional_aiguard_evidence_types must be a list when present", + ) + if isinstance(optional_aiguard_evidence_types, list): + invalid_optional_types = [ + item + for item in optional_aiguard_evidence_types + if not isinstance(item, str) or not item + ] + _record( + not invalid_optional_types, + errors, + "EdgeEnv handoff lab_bundle_alignment." + "optional_aiguard_evidence_types must contain non-empty strings", + ) + _record( + set(optional_aiguard_evidence_types) + == OPTIONAL_AIGUARD_EVIDENCE_TYPES, + errors, + "EdgeEnv handoff lab_bundle_alignment." + "optional_aiguard_evidence_types must match Lab-known optional " + "AIGuard evidence types", + ) + _record( + set(optional_aiguard_evidence_types).isdisjoint(REQUIRED_GUARD_TYPES), + errors, + "EdgeEnv handoff lab_bundle_alignment." + "optional_aiguard_evidence_types must remain separate from " + "required AIGuard evidence types", + ) + expected_report_markers = alignment.get("expected_report_markers") _record( isinstance(expected_report_markers, list), @@ -1844,6 +1887,19 @@ def _validate_external_aiguard_evidence_alignment( ) +def _has_optional_aiguard_evidence_declaration( + handoff: dict[str, Any], +) -> bool: + alignment = handoff.get("lab_bundle_alignment") + if not isinstance(alignment, dict): + return False + optional_types = alignment.get("optional_aiguard_evidence_types") + return ( + isinstance(optional_types, list) + and set(optional_types) == OPTIONAL_AIGUARD_EVIDENCE_TYPES + ) + + def _validate_remote_runtime_event_summary_evidence( item: dict[str, Any], index: int, @@ -3075,12 +3131,15 @@ def _write_summary( manifest_path: Path, errors: list[str], edgeenv_handoff_present: bool, + optional_aiguard_evidence_declared: bool, ) -> None: if not path: return contract_markers = list(SUMMARY_CONTRACT_MARKERS) if edgeenv_handoff_present: contract_markers.extend(EDGEENV_HANDOFF_SUMMARY_CONTRACT_MARKERS) + if optional_aiguard_evidence_declared: + contract_markers.append(EDGEENV_HANDOFF_OPTIONAL_AIGUARD_SUMMARY_MARKER) lines = [ "# Runtime Intelligence Bundle Manifest Gate", "", @@ -3113,9 +3172,13 @@ def main( manifest_payload = _load_json(manifest_path, "Runtime Intelligence bundle manifest") _validate_manifest_shape(manifest_payload, errors) handoff_payload: dict[str, Any] | None = None + optional_aiguard_evidence_declared = False if edgeenv_handoff: edgeenv_handoff_path = Path(edgeenv_handoff).resolve() handoff_payload = _load_json(edgeenv_handoff_path, "EdgeEnv handoff manifest") + optional_aiguard_evidence_declared = ( + _has_optional_aiguard_evidence_declaration(handoff_payload) + ) _validate_edgeenv_handoff_alignment( handoff_payload, handoff_path=edgeenv_handoff_path, @@ -3165,6 +3228,7 @@ def main( manifest_path=manifest_path, errors=errors, edgeenv_handoff_present=bool(edgeenv_handoff), + optional_aiguard_evidence_declared=optional_aiguard_evidence_declared, ) if errors: rprint("[red]Runtime Intelligence bundle manifest gate failed.[/red]") diff --git a/scripts/check_runtime_intelligence_ci_artifacts.py b/scripts/check_runtime_intelligence_ci_artifacts.py index 51218cf..88ef8a4 100644 --- a/scripts/check_runtime_intelligence_ci_artifacts.py +++ b/scripts/check_runtime_intelligence_ci_artifacts.py @@ -72,6 +72,7 @@ "edgeenv_handoff: producer_lineage_guard_alignment validated", "edgeenv_handoff: orchestrator_task_event_rollup validated", "edgeenv_handoff: missing_telemetry_orchestrator_context validated", + "edgeenv_handoff: optional AIGuard evidence types declared", ) REQUIRED_LAB_EXPECTED_REPORT_MARKERS = ( "Runtime Intelligence Risk Summary", diff --git a/tests/test_runtime_intelligence_bundle_manifest.py b/tests/test_runtime_intelligence_bundle_manifest.py index 3a26370..6bf88f5 100644 --- a/tests/test_runtime_intelligence_bundle_manifest.py +++ b/tests/test_runtime_intelligence_bundle_manifest.py @@ -162,6 +162,8 @@ def test_runtime_intelligence_docs_describe_expected_report_markers(): for doc in (handoff_doc, ci_doc): assert "expected_report_markers" in doc + assert "optional_aiguard_evidence_types" in doc + assert "edgeenv_orchestrator_stale_drop_summary" in doc assert "Lab-owned Runtime Intelligence report contract" in doc for marker in REQUIRED_EXPECTED_REPORT_MARKERS: assert marker in doc @@ -337,6 +339,7 @@ def test_runtime_intelligence_bundle_manifest_gate_validates_edgeenv_handoff( "edgeenv_handoff: external AIGuard evidence requirements declared" in summary ) + assert "edgeenv_handoff: optional AIGuard evidence types declared" in summary def test_runtime_intelligence_bundle_manifest_gate_fails_for_bad_seed_run_config( @@ -631,6 +634,36 @@ def test_runtime_intelligence_bundle_manifest_gate_fails_for_missing_external_gu ) in summary +def test_runtime_intelligence_bundle_manifest_gate_fails_for_bad_optional_guard_type( + tmp_path, +): + handoff = json.loads(EDGEENV_HANDOFF.read_text(encoding="utf-8")) + handoff["lab_bundle_alignment"]["optional_aiguard_evidence_types"] = [ + "runtime_queue_overload", + "unknown_optional_guard_type", + ] + handoff_path = tmp_path / "edgeenv_lab_handoff_manifest.json" + handoff_path.write_text(json.dumps(handoff), encoding="utf-8") + summary_path = tmp_path / "bundle_manifest_gate_summary.md" + + result = manifest_gate( + manifest=str(MANIFEST), + edgeenv_handoff=str(handoff_path), + summary_out=str(summary_path), + ) + + assert result == 2 + summary = summary_path.read_text(encoding="utf-8") + assert ( + "optional_aiguard_evidence_types must match Lab-known optional " + "AIGuard evidence types" + ) in summary + assert ( + "optional_aiguard_evidence_types must remain separate from required " + "AIGuard evidence types" + ) in summary + + def test_runtime_intelligence_bundle_manifest_gate_fails_for_missing_report_marker( tmp_path, ): diff --git a/tests/test_runtime_intelligence_ci_template.py b/tests/test_runtime_intelligence_ci_template.py index 8cea2e0..1ae1ed2 100644 --- a/tests/test_runtime_intelligence_ci_template.py +++ b/tests/test_runtime_intelligence_ci_template.py @@ -227,6 +227,7 @@ def test_runtime_intelligence_ci_artifact_gate_passes_for_expected_outputs(tmp_p "- edgeenv_handoff: runtime_telemetry_history validated", "- edgeenv_handoff: remote_dispatch_boundary preserved", "- edgeenv_handoff: external AIGuard evidence requirements declared", + "- edgeenv_handoff: optional AIGuard evidence types declared", "- edgeenv_handoff: device_local_producer_lineage validated", "- edgeenv_handoff: fixture_matrix_context validated", "- edgeenv_handoff: producer_lineage_guard_alignment validated", @@ -527,6 +528,7 @@ def test_runtime_intelligence_ci_artifact_gate_fails_for_missing_lab_marker_cont "- edgeenv_handoff: runtime_telemetry_history validated", "- edgeenv_handoff: remote_dispatch_boundary preserved", "- edgeenv_handoff: external AIGuard evidence requirements declared", + "- edgeenv_handoff: optional AIGuard evidence types declared", "- edgeenv_handoff: device_local_producer_lineage validated", "- edgeenv_handoff: fixture_matrix_context validated", "- edgeenv_handoff: producer_lineage_guard_alignment validated", @@ -892,6 +894,7 @@ def test_runtime_intelligence_ci_artifact_gate_fails_for_failed_deployment_risk( "- edgeenv_handoff: runtime_telemetry_history validated", "- edgeenv_handoff: remote_dispatch_boundary preserved", "- edgeenv_handoff: external AIGuard evidence requirements declared", + "- edgeenv_handoff: optional AIGuard evidence types declared", "- edgeenv_handoff: device_local_producer_lineage validated", "- edgeenv_handoff: fixture_matrix_context validated", "- edgeenv_handoff: producer_lineage_guard_alignment validated", diff --git a/tests/test_runtime_intelligence_smoke_script.py b/tests/test_runtime_intelligence_smoke_script.py index a91711e..c76a1e6 100644 --- a/tests/test_runtime_intelligence_smoke_script.py +++ b/tests/test_runtime_intelligence_smoke_script.py @@ -110,6 +110,7 @@ def test_runtime_intelligence_smoke_script_runs_artifact_chain(tmp_path): "edgeenv_handoff: external AIGuard evidence requirements declared" in bundle_summary ) + assert "edgeenv_handoff: optional AIGuard evidence types declared" in bundle_summary assert "edgeenv_handoff: device_local_producer_lineage validated" in bundle_summary assert ( "edgeenv_handoff: producer_lineage_guard_alignment validated"