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
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
},
"trigger_reason": "Break-glass mode was enabled on a sensitive service.",
"correlation_window_minutes": 15,
"bounded_correlation_reason": "Attached evidence shares target_system 'vault-gateway' and falls within 15 minutes after the triggering change.",
"bounded_correlation_reason": "No policy denials or follow-on events were attached for target_system 'vault-gateway' within 15 minutes after the triggering change.",
"attached_policy_denials": [],
"attached_follow_on_events": [],
"evidence_counts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ Follow-on events:
- Trigger reason: Break-glass mode was enabled on a sensitive service.
- Attached policy denials: 0
- Attached follow-on events: 0
- Bounded correlation: Attached evidence shares target_system 'vault-gateway' and falls within 15 minutes after the triggering change.
- Bounded correlation: No policy denials or follow-on events were attached for target_system 'vault-gateway' within 15 minutes after the triggering change.

No nearby supporting evidence fell inside the bounded correlation window.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@
"policy_denials": 0,
"follow_on_events": 0
},
"bounded_correlation_reason": "Attached evidence shares target_system 'vault-gateway' and falls within 15 minutes after the triggering change."
"bounded_correlation_reason": "No policy denials or follow-on events were attached for target_system 'vault-gateway' within 15 minutes after the triggering change."
}
]
4 changes: 4 additions & 0 deletions docs/evidence-pipeline-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ artifact a bounded evidence summary rather than an incident verdict: it does
not claim `vault-gateway` was cleared, only that no additional evidence was
attached under the demo's bounded correlation rules.

When both attachment arrays are empty, `bounded_correlation_reason` explicitly
states that no policy denials or follow-on events were attached for that target
and window.

## Verification

Run:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"trigger_reason": "Break-glass mode was enabled on a sensitive service.",
"correlation_window_minutes": 15,
"bounded_correlation_reason": "Attached evidence shares target_system 'vault-gateway' and falls within 15 minutes after the triggering change.",
"bounded_correlation_reason": "No policy denials or follow-on events were attached for target_system 'vault-gateway' within 15 minutes after the triggering change.",
"evidence_counts": {
"policy_denials": 0,
"follow_on_events": 0
Expand Down
16 changes: 12 additions & 4 deletions src/telemetry_lab/config_change_investigation_demo/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,17 @@ def build_investigations(
and change_time <= event["timestamp"] <= window_end
]

if attached_denials or attached_follow_on:
bounded_reason = (
f"Attached evidence shares target_system '{target_system}' and falls within "
f"{correlation_minutes} minutes after the triggering change."
)
else:
bounded_reason = (
"No policy denials or follow-on events were attached for target_system "
f"'{target_system}' within {correlation_minutes} minutes after the triggering change."
)

investigations.append(
{
"investigation_id": str(hit["investigation_id"]),
Expand All @@ -445,10 +456,7 @@ def build_investigations(
"triggering_change": dict(change_event),
"trigger_reason": str(hit["reason"]),
"correlation_window_minutes": correlation_minutes,
"bounded_correlation_reason": (
f"Attached evidence shares target_system '{target_system}' and falls within "
f"{correlation_minutes} minutes after the triggering change."
),
"bounded_correlation_reason": bounded_reason,
"attached_policy_denials": attached_denials,
"attached_follow_on_events": attached_follow_on,
"evidence_counts": {
Expand Down
50 changes: 50 additions & 0 deletions tests/test_config_change_investigation_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

from telemetry_lab.config_change_investigation_demo import default_demo_root, run_demo
from telemetry_lab.config_change_investigation_demo.pipeline import (
build_investigation_report,
build_investigation_summary,
build_investigations,
evaluate_risky_config_changes,
load_jsonl,
Expand Down Expand Up @@ -105,6 +107,54 @@ def test_build_investigations_uses_bounded_system_and_time_correlation() -> None
)


def test_bounded_reason_explicitly_reports_zero_evidence() -> None:
demo_root, config, changes, _, _ = _load_demo_inputs()
hits = evaluate_risky_config_changes(changes, config["rules"])
hit = next(item for item in hits if item["investigation_id"] == "CCI-003")
investigations = build_investigations([hit], [], [], correlation_minutes=15)
investigation = investigations[0]
expected_reason = (
"No policy denials or follow-on events were attached for target_system "
"'vault-gateway' within 15 minutes after the triggering change."
)

assert investigation["evidence_counts"] == {"policy_denials": 0, "follow_on_events": 0}
assert investigation["severity"] == "high"
assert investigation["bounded_correlation_reason"] == expected_reason
summary = build_investigation_summary(investigations, correlation_minutes=15)
assert summary[0]["bounded_correlation_reason"] == expected_reason
report = build_investigation_report(changes, [hit], investigations, correlation_minutes=15)
assert f"- Bounded correlation: {expected_reason}" in report
assert "No nearby supporting evidence fell inside the bounded correlation window." in report
assert "Attached evidence shares" not in report
example = _load_json_file(
demo_root.parents[1] / "docs/reviewer-pack-v0.6.0/bounded-case-no-evidence-example.json"
)
assert example["investigation"]["bounded_correlation_reason"] == expected_reason


@pytest.mark.parametrize(
"with_denials,with_follow_on", [(True, False), (False, True), (True, True)]
)
def test_bounded_reason_preserves_nonempty_wording(
with_denials: bool, with_follow_on: bool
) -> None:
_, config, changes, denials, follow_on = _load_demo_inputs()
hits = evaluate_risky_config_changes(changes, config["rules"])
hit = next(item for item in hits if item["investigation_id"] == "CCI-001")
investigation = build_investigations(
[hit],
denials if with_denials else [],
follow_on if with_follow_on else [],
correlation_minutes=15,
)[0]

assert investigation["bounded_correlation_reason"] == (
"Attached evidence shares target_system 'identity-proxy' and falls within "
"15 minutes after the triggering change."
)


def test_build_investigations_includes_evidence_on_window_end_only() -> None:
change_time = parse_timestamp("2026-03-20T09:00:00Z")
rule_hits = [
Expand Down
Loading