From 396e6e59003ddbacd7d48381393f7da07b849c1f Mon Sep 17 00:00:00 2001 From: hyeokjun32 Date: Sat, 30 May 2026 00:18:38 +0900 Subject: [PATCH] feat: label Jetson preservation report rows --- README.ko.md | 2 ++ README.md | 4 +++ .../runtime_intelligence_gitlab_artifacts.md | 2 +- .../edgeenv_runtime_regression_lab_handoff.md | 1 + inferedgelab/report/runtime_intelligence.py | 14 +++++++++- ...ck_runtime_intelligence_artifact_bundle.py | 9 +++++++ tests/test_report_generators.py | 8 +++--- ...test_runtime_intelligence_artifact_gate.py | 27 +++++++++++++++++++ ...ntime_intelligence_evidence_chain_smoke.py | 4 +++ 9 files changed, 66 insertions(+), 5 deletions(-) diff --git a/README.ko.md b/README.ko.md index b12fe0b..0c81b74 100644 --- a/README.ko.md +++ b/README.ko.md @@ -228,6 +228,8 @@ Runtime Intelligence report에서 읽어야 할 핵심 row: - Runtime history seed `run_config` traceability - Orchestrator device-local producer lineage - Lab EdgeEnv preservation context marker +- Jetson/device-local preservation row의 `identity=jetson_device_local_preservation` + 및 `path=device_local_starter` 식별 label - AIGuard deterministic anomaly evidence - Lab-owned deployment decision diff --git a/README.md b/README.md index fb9e631..8ec520e 100644 --- a/README.md +++ b/README.md @@ -507,6 +507,10 @@ preservation context` row with `lab_report_preservation_context_present=True`, `lab_preservation=present`, and `lab_context=present`. This keeps Lab's Runtime Intelligence artifact gate aligned with the entrypoint evidence index without making EdgeEnv the deployment decision owner. +The companion `Jetson/device-local EdgeEnv preservation run` row starts with +`identity=jetson_device_local_preservation` and, when available, +`path=device_local_starter`, so reviewers can spot the preserved Jetson or +device-local run before reading queue, resource, and producer details. If the Orchestrator feed includes `runtime_task_event_summary`, Lab also renders a task-level event rollup showing which workload had scheduler delay, deadline misses, fallback decisions, or drop/policy reasons. This is report navigation context only; Lab still owns the deployment decision. diff --git a/docs/ci/runtime_intelligence_gitlab_artifacts.md b/docs/ci/runtime_intelligence_gitlab_artifacts.md index 85e17b7..e019fc3 100644 --- a/docs/ci/runtime_intelligence_gitlab_artifacts.md +++ b/docs/ci/runtime_intelligence_gitlab_artifacts.md @@ -185,7 +185,7 @@ EdgeEnv handoff summary and AIGuard deterministic evidence agree on producer-lineage guard-alignment run IDs. This keeps the cross-repo marker check file-based and does not make AIGuard a deployment decision owner. -The artifact gate is implemented by `scripts/check_runtime_intelligence_artifact_bundle.py`. It checks the generated Markdown / HTML report for the required Runtime Intelligence rows, including Lab ownership, EdgeEnv comparability, telemetry coverage-gap markers, Orchestrator operation feed context, Orchestrator task event rollup, Lab EdgeEnv preservation context, Orchestrator `operation_risk_summary` navigation context, AIGuard runtime operation anomalies, AIGuard `edgeenv_orchestrator_operation_risk_summary` evidence, AIGuard `edgeenv_orchestrator_task_event_rollup` evidence, remote dispatch starter event summary, `Remote fallback starter evidence`, `edgeenv_orchestrator_producer_lineage`, `runtime_history_seed_run_config_traceability`, `remote_execution_recovered_by_fallback`, and triggered deployment review rules. +The artifact gate is implemented by `scripts/check_runtime_intelligence_artifact_bundle.py`. It checks the generated Markdown / HTML report for the required Runtime Intelligence rows, including Lab ownership, EdgeEnv comparability, telemetry coverage-gap markers, Orchestrator operation feed context, Orchestrator task event rollup, Lab EdgeEnv preservation context, Jetson/device-local preservation identity labels, Orchestrator `operation_risk_summary` navigation context, AIGuard runtime operation anomalies, AIGuard `edgeenv_orchestrator_operation_risk_summary` evidence, AIGuard `edgeenv_orchestrator_task_event_rollup` evidence, remote dispatch starter event summary, `Remote fallback starter evidence`, `edgeenv_orchestrator_producer_lineage`, `runtime_history_seed_run_config_traceability`, `remote_execution_recovered_by_fallback`, and triggered deployment review rules. The CI artifact gate is implemented by `scripts/check_runtime_intelligence_ci_artifacts.py`. It runs in the deployment-risk stage and verifies that the collected optional GitLab artifacts include the manifest gate summary, AIGuard handoff alignment artifact, report gate summary, Runtime Intelligence Risk Summary report, portfolio demo status, and the validated contract markers from the bundle manifest gate. This keeps the final CI gate file-based and deterministic without turning GitLab into a runtime control plane. The same CI artifact gate also checks the copied diff --git a/docs/portfolio/edgeenv_runtime_regression_lab_handoff.md b/docs/portfolio/edgeenv_runtime_regression_lab_handoff.md index e238e86..0f20bb1 100644 --- a/docs/portfolio/edgeenv_runtime_regression_lab_handoff.md +++ b/docs/portfolio/edgeenv_runtime_regression_lab_handoff.md @@ -188,6 +188,7 @@ Expected Lab behavior: - Additional Lab test fixtures under `tests/fixtures/edgeenv_regression/` mirror EdgeEnv replay examples for candidate telemetry gaps and execution sequence inversion. These fixture smokes verify that replay warnings become Lab-owned report context without making Lab recompute EdgeEnv comparability. - Markdown/HTML reports include a `Runtime Intelligence Risk Summary` that summarizes EdgeEnv comparability/regression, telemetry replay gaps, Runtime history seed/run_config traceability, AIGuard deterministic evidence, and the Lab-owned deployment decision in one reviewer-facing table. - When EdgeEnv includes preserved Orchestrator feed context, the `Runtime Intelligence Risk Summary` surfaces queue, thermal, throttling, memory, fallback context, and compact `operation_risk_summary` markers as supplemental runtime evidence. +- The Jetson/device-local preservation row starts with `identity=jetson_device_local_preservation` and the device-local path marker such as `path=device_local_starter` when available, making the preserved Jetson EdgeEnv run easier to identify before reviewers inspect detailed queue/resource context. - `operation_risk_summary` markers are shown as navigation context only: queue-pressure reason, max-pressure task, worker-health reason, and producer/device-local event counts do not become EdgeEnv regression deltas, comparability fields, or a Lab deployment decision override. - If the preserved Orchestrator feed includes `runtime_task_event_summary`, Lab also renders a task-level event rollup for scheduler delay, deadline miss, fallback, policy reason, and drop reason markers. This helps reviewers identify the affected workload without making Orchestrator the decision owner. - When `--guard-analysis` is provided, Lab ingests the precomputed AIGuard artifact as evidence without requiring AIGuard to be installed in the Lab environment. diff --git a/inferedgelab/report/runtime_intelligence.py b/inferedgelab/report/runtime_intelligence.py index a3cb257..146fdcb 100644 --- a/inferedgelab/report/runtime_intelligence.py +++ b/inferedgelab/report/runtime_intelligence.py @@ -440,7 +440,10 @@ def _edgeenv_preservation_run_label( if not has_preservation_marker: return "" - parts: list[str] = [] + parts: list[str] = ["identity=jetson_device_local_preservation"] + stage_paths = _producer_stage_paths(stage_labels) + if stage_paths: + parts.append("path=" + ",".join(stage_paths)) run_id = _first_present( operation_context.get("run_id"), candidate_context.get("run_id"), @@ -478,6 +481,15 @@ def _producer_stage_labels(stage_by_task: Any) -> list[str]: return labels +def _producer_stage_paths(stage_labels: list[str]) -> list[str]: + paths: list[str] = [] + for label in stage_labels: + stage = label.split(":", 1)[1] if ":" in label else label + if _is_device_local_preservation_marker(stage) and stage not in paths: + paths.append(stage) + return paths + + def _is_device_local_preservation_marker(value: str) -> bool: normalized = value.lower() return "device_local" in normalized or "jetson" in normalized diff --git a/scripts/check_runtime_intelligence_artifact_bundle.py b/scripts/check_runtime_intelligence_artifact_bundle.py index 3d77b82..acfaf52 100644 --- a/scripts/check_runtime_intelligence_artifact_bundle.py +++ b/scripts/check_runtime_intelligence_artifact_bundle.py @@ -29,6 +29,11 @@ "| Orchestrator operation risk summary | candidate: " "queue=queue_backlog_threshold_exceeded" ), + "jetson_edgeenv_preservation_identity": ( + "| Jetson/device-local EdgeEnv preservation run | candidate: " + "identity=jetson_device_local_preservation, path=device_local_starter, " + "run=edgeenv-smoke-candidate" + ), "orchestrator_task_event_rollup": ( "| Orchestrator task event rollup | candidate: " "vision_agent(delay=1,miss=1,max_delay_cycles=3,max_wait_ms=15," @@ -147,6 +152,10 @@ ), "aiguard_guard_alignment": "AIGuard producer-lineage guard alignment", "aiguard_device_local_producer_source": "device_local_cli_override", + "jetson_edgeenv_preservation_identity": ( + "identity=jetson_device_local_preservation, path=device_local_starter, " + "run=edgeenv-smoke-candidate" + ), "runtime_history_seed": "Runtime telemetry history seed", "runtime_history_seed_run_config": "Runtime history seed run_config", "aiguard_history_seed_handoff": "AIGuard history seed handoff", diff --git a/tests/test_report_generators.py b/tests/test_report_generators.py index 1dd5ea1..bfd7ab5 100644 --- a/tests/test_report_generators.py +++ b/tests/test_report_generators.py @@ -831,7 +831,8 @@ def test_generate_compare_markdown_summarizes_orchestrator_context_risk(): ) in text assert ( "| Jetson/device-local EdgeEnv preservation run | candidate: " - "run=candidate, device_local_events=15, resource=tegrastats_timeline, " + "identity=jetson_device_local_preservation, run=candidate, " + "device_local_events=15, resource=tegrastats_timeline, " "queue=queue_backlog_threshold_exceeded |" ) in text assert ( @@ -1146,8 +1147,9 @@ def test_generate_compare_html_summarizes_orchestrator_context_risk(): assert "lab_report_preservation_context_present=True" in html assert "lab_preservation=present" in html assert ( - "candidate: run=candidate, device_local_events=15, " - "resource=tegrastats_timeline, queue=queue_backlog_threshold_exceeded" + "candidate: identity=jetson_device_local_preservation, run=candidate, " + "device_local_events=15, resource=tegrastats_timeline, " + "queue=queue_backlog_threshold_exceeded" ) in html assert "runtime_queue_overload, runtime_thermal_instability" in html assert "AIGuard Orchestrator context handoff" in html diff --git a/tests/test_runtime_intelligence_artifact_gate.py b/tests/test_runtime_intelligence_artifact_gate.py index bff4425..ec8334b 100644 --- a/tests/test_runtime_intelligence_artifact_gate.py +++ b/tests/test_runtime_intelligence_artifact_gate.py @@ -184,6 +184,33 @@ def test_runtime_intelligence_artifact_gate_fails_when_lab_preservation_context_ assert "`lab_edgeenv_preservation_context`" in summary +def test_runtime_intelligence_artifact_gate_fails_when_jetson_identity_is_missing( + tmp_path, +): + markdown_path, html_path = _write_runtime_intelligence_reports(tmp_path) + markdown = markdown_path.read_text(encoding="utf-8").replace( + "identity=jetson_device_local_preservation", + "identity marker removed", + ) + html = html_path.read_text(encoding="utf-8").replace( + "identity=jetson_device_local_preservation", + "identity marker removed", + ) + markdown_path.write_text(markdown, encoding="utf-8") + html_path.write_text(html, encoding="utf-8") + summary_path = tmp_path / "gate_summary.md" + + result = gate_main( + markdown=str(markdown_path), + html=str(html_path), + summary_out=str(summary_path), + ) + + assert result == 2 + summary = summary_path.read_text(encoding="utf-8") + assert "`jetson_edgeenv_preservation_identity`" in summary + + def test_runtime_intelligence_artifact_gate_fails_when_remote_summary_is_missing( tmp_path, ): diff --git a/tests/test_runtime_intelligence_evidence_chain_smoke.py b/tests/test_runtime_intelligence_evidence_chain_smoke.py index 0bd6ae4..351bc78 100644 --- a/tests/test_runtime_intelligence_evidence_chain_smoke.py +++ b/tests/test_runtime_intelligence_evidence_chain_smoke.py @@ -383,6 +383,7 @@ def test_runtime_intelligence_chain_smoke_ingests_precomputed_guard_artifact(): assert "| Orchestrator context attached runs | candidate |" in bundle["markdown"] assert ( "| Jetson/device-local EdgeEnv preservation run | candidate: " + "identity=jetson_device_local_preservation, path=device_local_starter, " "run=edgeenv-smoke-candidate, sources=device_local_cli_override, " "stages=vision_agent:device_local_starter, device_local_events=2, " "resource=tegrastats_timeline, queue=queue_backlog_threshold_exceeded |" @@ -495,6 +496,7 @@ def test_compare_cmd_runtime_intelligence_chain_writes_markdown_and_html( assert "lab_report_preservation_context_present=True" in markdown assert "lab_preservation=present" in markdown assert ( + "identity=jetson_device_local_preservation, path=device_local_starter, " "run=edgeenv-smoke-candidate, sources=device_local_cli_override, " "stages=vision_agent:device_local_starter, device_local_events=2, " "resource=tegrastats_timeline, queue=queue_backlog_threshold_exceeded" @@ -526,6 +528,8 @@ def test_compare_cmd_runtime_intelligence_chain_writes_markdown_and_html( assert "Lab EdgeEnv preservation context" in html assert "lab_report_preservation_context_present=True" in html assert "lab_preservation=present" in html + assert "identity=jetson_device_local_preservation" in html + assert "path=device_local_starter" in html assert "run=edgeenv-smoke-candidate" in html assert "Orchestrator task event rollup" in html assert (