Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions docs/runtime-telemetry-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ Newer Orchestrator feeds can also declare `edgeenv_mapping_hint` fields. EdgeEnv
preserves these hints and validates them when present: Orchestrator may map only
supplemental candidate operation context to
`runtime_telemetry_context.candidate`, while EdgeEnv remains the owner of
`runtime_telemetry_context.history.telemetry_coverage`.
`runtime_telemetry_context.history.telemetry_coverage`. When the feed declares
`candidate_context_required_fields`, EdgeEnv checks that the mapping hint and the
candidate context still include `run_id`, `telemetry_source`, `operation`, and
`resource` before the context can reach regression reports or Lab handoff
manifests.

Replay validation command:

Expand Down Expand Up @@ -121,8 +125,15 @@ The history artifact uses this top-level shape:
"not_a_comparability_gate": true,
"edgeenv_mapping_hint": {
"copy_candidate_context_to": "runtime_telemetry_context.candidate",
"operation_context_role": "supplemental",
"coverage_summary_owner": "edgeenv",
"coverage_summary_path": "runtime_telemetry_context.history.telemetry_coverage"
"coverage_summary_path": "runtime_telemetry_context.history.telemetry_coverage",
"candidate_context_required_fields": [
"run_id",
"telemetry_source",
"operation",
"resource"
]
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions tests/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
ORCHESTRATOR_EDGEENV_COVERAGE_SUMMARY_OWNER,
ORCHESTRATOR_EDGEENV_HISTORY_COVERAGE_PATH,
ORCHESTRATOR_EDGEENV_OPERATION_CONTEXT_ROLE,
ORCHESTRATOR_EDGEENV_REQUIRED_CANDIDATE_FIELDS,
)
from inferedge_env.result.writer import ResultArtifactWriter
from inferedge_env.runners.base import RunnerResult
Expand Down Expand Up @@ -271,9 +272,18 @@ def test_regression_attaches_orchestrator_feed_as_supplemental_context(
assert candidate_context["orchestrator_operation_context"]["edgeenv_mapping_hint"][
"coverage_summary_path"
] == ORCHESTRATOR_EDGEENV_HISTORY_COVERAGE_PATH
assert candidate_context["orchestrator_operation_context"]["edgeenv_mapping_hint"][
"operation_context_role"
] == ORCHESTRATOR_EDGEENV_OPERATION_CONTEXT_ROLE
assert candidate_context["orchestrator_operation_context"]["edgeenv_mapping_hint"][
"candidate_context_required_fields"
] == [*ORCHESTRATOR_EDGEENV_REQUIRED_CANDIDATE_FIELDS]
assert candidate_context["orchestrator_operation_context"]["candidate_context"][
"operation"
]["queue_depth"] == 7
assert candidate_context["orchestrator_operation_context"]["candidate_context"][
"telemetry_source"
] == "inferedge_orchestrator_operation_summary"
assert (
"Orchestrator operation context is supplemental evidence, not a regression judgement."
in context["notes"]
Expand Down
28 changes: 28 additions & 0 deletions tests/test_runtime_intelligence_lab_handoff.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,34 @@ def test_runtime_intelligence_lab_handoff_rejects_bad_orchestrator_mapping(
)


def test_runtime_intelligence_lab_handoff_rejects_incomplete_mapping_required_fields(
tmp_path,
):
baseline_path, candidate_path, regression_path, history_path = _write_handoff_files(
tmp_path
)
regression = json.loads(regression_path.read_text(encoding="utf-8"))
regression["runtime_telemetry_context"]["candidate"][
"orchestrator_operation_context"
]["edgeenv_mapping_hint"]["candidate_context_required_fields"] = [
"run_id",
"operation",
"resource",
]
regression_path.write_text(json.dumps(regression), encoding="utf-8")

with pytest.raises(
RuntimeIntelligenceLabHandoffError,
match="candidate_context_required_fields must include telemetry_source",
):
build_runtime_intelligence_lab_handoff_manifest(
baseline_result_path=baseline_path,
candidate_result_path=candidate_path,
edgeenv_regression_report_path=regression_path,
telemetry_history_path=history_path,
)


def _write_handoff_files(tmp_path):
baseline_path = tmp_path / "baseline-result.json"
candidate_path = tmp_path / "candidate-result.json"
Expand Down
6 changes: 6 additions & 0 deletions tests/test_runtime_telemetry_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ORCHESTRATOR_EDGEENV_COVERAGE_SUMMARY_OWNER,
ORCHESTRATOR_EDGEENV_HISTORY_COVERAGE_PATH,
ORCHESTRATOR_EDGEENV_OPERATION_CONTEXT_ROLE,
ORCHESTRATOR_EDGEENV_REQUIRED_CANDIDATE_FIELDS,
ORCHESTRATOR_TELEMETRY_FEED_SCHEMA_VERSION,
RUNTIME_TELEMETRY_HISTORY_SCHEMA_VERSION,
RuntimeTelemetryHistoryError,
Expand Down Expand Up @@ -201,6 +202,11 @@ def test_build_runtime_telemetry_history_attaches_orchestrator_feed_context(
assert context["edgeenv_mapping_hint"]["coverage_summary_path"] == (
ORCHESTRATOR_EDGEENV_HISTORY_COVERAGE_PATH
)
assert context["edgeenv_mapping_hint"]["candidate_context_required_fields"] == [
*ORCHESTRATOR_EDGEENV_REQUIRED_CANDIDATE_FIELDS
]
for field in ORCHESTRATOR_EDGEENV_REQUIRED_CANDIDATE_FIELDS:
assert field in context["candidate_context"]
assert "not a regression judgement" in payload["notes"][3]


Expand Down
Loading