feature-rc/SIENTIAPDE-2164 -fix: apply Temporal replay-safe unpacking and guard against missing filter counters (review findings)
This commit is contained in:
@@ -362,7 +362,13 @@ class Gates(SientiaMonitoring):
|
|||||||
{
|
{
|
||||||
'name': fil,
|
'name': fil,
|
||||||
'policy': path_flag,
|
'policy': path_flag,
|
||||||
'counter': input_filter_counters[fil](data, filter_config),
|
# `.get(..., lambda *_: 0)`, not `[fil]`: a filter added to
|
||||||
|
# `input_filter_functions` without a matching counter here degrades to
|
||||||
|
# counter=0 instead of a raw KeyError crashing this prediction (review
|
||||||
|
# finding, 2026-09-30 — see test enforcing key parity between the two).
|
||||||
|
'counter': input_filter_counters.get(fil, lambda *_: 0)(
|
||||||
|
data, filter_config
|
||||||
|
),
|
||||||
}
|
}
|
||||||
for fil, filter_config in matched
|
for fil, filter_config in matched
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -133,8 +133,17 @@ class PredictionProcess:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# `_metadata_id` (prediction_metadata document id, only non-None when path_flag ends up
|
# `_metadata_id` (prediction_metadata document id, only non-None when path_flag ends up
|
||||||
# CONTINUE) isn't threaded through yet — SIENTIAPDE-2167 wires it to Postgres.
|
# CONTINUE) isn't threaded through yet — SIENTIAPDE-2167 wires it to Postgres. Star-unpack
|
||||||
path_flag, confidence, comment, _metadata_id = await workflow.execute_local_activity_method(
|
# rather than a fixed 4-tuple: `input_gate` is a local activity, so its result is recorded
|
||||||
|
# in workflow history; an execution already in flight when this field was added would
|
||||||
|
# replay a 3-element result here, and exact unpacking would raise ValueError on replay
|
||||||
|
# (review finding, 2026-09-30).
|
||||||
|
(
|
||||||
|
path_flag,
|
||||||
|
confidence,
|
||||||
|
comment,
|
||||||
|
*_metadata_id,
|
||||||
|
) = await workflow.execute_local_activity_method(
|
||||||
Activities.input_gate,
|
Activities.input_gate,
|
||||||
gate_input,
|
gate_input,
|
||||||
retry_policy=retry_policy,
|
retry_policy=retry_policy,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from sientia_do.notifications.models import NotificationLevel
|
|||||||
from sientia_do.observability.metrics_controller import MetricsController
|
from sientia_do.observability.metrics_controller import MetricsController
|
||||||
from sientia_do.observability.sientia_monitoring import SientiaMonitoring
|
from sientia_do.observability.sientia_monitoring import SientiaMonitoring
|
||||||
|
|
||||||
from laborious.activities.gates import Gates
|
from laborious.activities.gates import Gates, input_filter_counters, input_filter_functions
|
||||||
|
|
||||||
|
|
||||||
@fixture(autouse=True)
|
@fixture(autouse=True)
|
||||||
@@ -136,6 +136,13 @@ def test_write_prediction_metadata_insert_failure_swallowed(gates_activity, mong
|
|||||||
gates_activity.error.assert_called_once()
|
gates_activity.error.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
def test_input_filter_counters_covers_every_input_filter_function():
|
||||||
|
# A filter added to input_filter_functions without a matching entry here would degrade to
|
||||||
|
# counter=0 (see the `.get(..., lambda *_: 0)` fallback in input_gate) instead of crashing —
|
||||||
|
# but this test should still catch the gap before it ships (review finding, 2026-09-30).
|
||||||
|
assert set(input_filter_counters) == set(input_filter_functions)
|
||||||
|
|
||||||
|
|
||||||
def test_input_gate_invalid_filter(gates_activity, mongo: MagicMock):
|
def test_input_gate_invalid_filter(gates_activity, mongo: MagicMock):
|
||||||
# Arrange
|
# Arrange
|
||||||
input_data = {
|
input_data = {
|
||||||
|
|||||||
Reference in New Issue
Block a user