2727
2828SOURCE_SCHEMA_VERSION = "qsl_execution_evidence_source_snapshot.v1"
2929RUNTIME_REPORT_SCHEMA_VERSION = "runtime_report.v1"
30+ EXECUTION_RECEIPT_SCHEMA_VERSION = "qsl_execution_receipt.v1"
3031_PLATFORM_ALIASES = {
3132 "alpaca" : "alpaca" ,
3233 "binance" : "binance" ,
4445_REVISION = re .compile (r"^[0-9a-f]{40}$" )
4546_IDENTIFIER = re .compile (r"^[A-Za-z0-9._=-]{1,128}$" )
4647_FORBIDDEN_TEXT = re .compile (r"(?:secret|token|password|credential|api[_-]?key|account|order|fill|position|capital)" , re .IGNORECASE )
48+ _EXECUTION_RECEIPT_ID = re .compile (r"^execution-receipt\.[0-9a-f]{32}$" )
49+ _EXECUTION_RECEIPT_OUTCOMES = frozenset (
50+ {
51+ "not_due" ,
52+ "no_action" ,
53+ "risk_blocked" ,
54+ "submitted" ,
55+ "broker_acknowledged" ,
56+ "partially_filled" ,
57+ "filled" ,
58+ "reconciliation_required" ,
59+ "failed" ,
60+ }
61+ )
62+ _EXECUTION_RECEIPT_CONFIRMATIONS = frozenset (
63+ {
64+ "not_applicable" ,
65+ "not_observed" ,
66+ "acknowledged" ,
67+ "partially_filled" ,
68+ "filled" ,
69+ "reconciliation_required" ,
70+ }
71+ )
72+ _EXECUTION_RECEIPT_OUTCOME_CONFIRMATIONS = {
73+ "not_due" : frozenset ({"not_applicable" }),
74+ "no_action" : frozenset ({"not_applicable" }),
75+ "risk_blocked" : frozenset ({"not_applicable" }),
76+ "submitted" : frozenset ({"not_observed" }),
77+ "broker_acknowledged" : frozenset ({"acknowledged" }),
78+ "partially_filled" : frozenset ({"partially_filled" }),
79+ "filled" : frozenset ({"filled" }),
80+ "reconciliation_required" : frozenset ({"reconciliation_required" }),
81+ "failed" : frozenset ({"not_applicable" , "not_observed" , "reconciliation_required" }),
82+ }
4783
4884
4985class ExecutionEvidenceProjectionError (ValueError ):
@@ -143,14 +179,23 @@ def _project_runtime_report(report: Mapping[str, Any]) -> tuple[dict[str, Any],
143179 raise ExecutionEvidenceProjectionError ("runtime_report_release_unattested" )
144180
145181 observed_at = _report_timestamp (report )
182+ execution_receipt = _project_execution_receipt (
183+ report .get ("execution_receipt" ),
184+ platform = platform ,
185+ strategy_profile = profile ,
186+ strategy_revision = revision ,
187+ execution_mode = execution_mode ,
188+ report_observed_at = observed_at ,
189+ )
146190 deployment_id = _deployment_id (
147191 platform = platform ,
148192 deploy_target = report .get ("deploy_target" ),
149193 service_name = report .get ("service_name" ),
150194 strategy_profile = profile ,
151195 environment = execution_mode ,
152196 )
153- return {
197+ target_execution , reason_code = _execution_evidence_from_receipt (execution_receipt )
198+ deployment = {
154199 "deployment_id" : deployment_id ,
155200 "strategy" : {
156201 "candidate_id" : profile ,
@@ -163,13 +208,101 @@ def _project_runtime_report(report: Mapping[str, Any]) -> tuple[dict[str, Any],
163208 "evidence" : {
164209 "strategy" : "verified" ,
165210 "target_data" : "pending" ,
166- "target_execution" : "pending" ,
211+ "target_execution" : target_execution ,
167212 },
168213 "recommendation" : {
169214 "code" : "parked" ,
170- "reason_code" : "target_execution_evidence_missing" ,
215+ "reason_code" : reason_code ,
171216 },
172- }, observed_at
217+ }
218+ if execution_receipt is not None :
219+ deployment ["execution_receipt" ] = execution_receipt
220+ return deployment , observed_at
221+
222+
223+ def _project_execution_receipt (
224+ value : object ,
225+ * ,
226+ platform : str ,
227+ strategy_profile : str ,
228+ strategy_revision : str ,
229+ execution_mode : str ,
230+ report_observed_at : datetime ,
231+ ) -> dict [str , str ] | None :
232+ """Project one exact, privacy-safe outcome receipt from a runtime report.
233+
234+ The report itself remains the source of identity. Any receipt that does
235+ not match its platform, strategy revision and lane is discarded instead of
236+ being used to make execution look verified.
237+ """
238+
239+ if value is None :
240+ return None
241+ receipt = _mapping (value , "runtime_report_execution_receipt_invalid" )
242+ expected_fields = {
243+ "schema_version" ,
244+ "receipt_id" ,
245+ "platform" ,
246+ "strategy_profile" ,
247+ "strategy_revision" ,
248+ "execution_mode" ,
249+ "outcome" ,
250+ "broker_confirmation" ,
251+ "observed_at" ,
252+ }
253+ if set (receipt ) != expected_fields or receipt .get ("schema_version" ) != EXECUTION_RECEIPT_SCHEMA_VERSION :
254+ raise ExecutionEvidenceProjectionError ("runtime_report_execution_receipt_invalid" )
255+ receipt_platform = _PLATFORM_ALIASES .get (str (receipt .get ("platform" ) or "" ).strip ().lower ())
256+ receipt_profile = _identity (receipt .get ("strategy_profile" ), "runtime_report_execution_receipt_invalid" )
257+ receipt_revision = str (receipt .get ("strategy_revision" ) or "" ).strip ()
258+ receipt_mode = str (receipt .get ("execution_mode" ) or "" ).strip ()
259+ outcome = str (receipt .get ("outcome" ) or "" ).strip ()
260+ confirmation = str (receipt .get ("broker_confirmation" ) or "" ).strip ()
261+ receipt_id = str (receipt .get ("receipt_id" ) or "" ).strip ()
262+ receipt_at = _receipt_timestamp (receipt .get ("observed_at" ))
263+ if (
264+ receipt_platform != platform
265+ or receipt_profile != strategy_profile
266+ or receipt_revision != strategy_revision
267+ or receipt_mode != execution_mode
268+ or not _REVISION .fullmatch (receipt_revision )
269+ or outcome not in _EXECUTION_RECEIPT_OUTCOMES
270+ or confirmation not in _EXECUTION_RECEIPT_CONFIRMATIONS
271+ or confirmation not in _EXECUTION_RECEIPT_OUTCOME_CONFIRMATIONS [outcome ]
272+ or not _EXECUTION_RECEIPT_ID .fullmatch (receipt_id )
273+ ):
274+ raise ExecutionEvidenceProjectionError ("runtime_report_execution_receipt_invalid" )
275+ expected_id = _execution_receipt_id (
276+ platform = receipt_platform ,
277+ strategy_profile = receipt_profile ,
278+ strategy_revision = receipt_revision ,
279+ execution_mode = receipt_mode ,
280+ outcome = outcome ,
281+ broker_confirmation = confirmation ,
282+ observed_at = _timestamp (receipt_at ),
283+ )
284+ if receipt_id != expected_id :
285+ raise ExecutionEvidenceProjectionError ("runtime_report_execution_receipt_invalid" )
286+ if receipt_at > report_observed_at + timedelta (minutes = 5 ) or receipt_at < report_observed_at - timedelta (hours = 24 ):
287+ raise ExecutionEvidenceProjectionError ("runtime_report_execution_receipt_timestamp_mismatch" )
288+ return {
289+ "outcome" : outcome ,
290+ "broker_confirmation" : confirmation ,
291+ "observed_at" : _timestamp (receipt_at ),
292+ }
293+
294+
295+ def _execution_evidence_from_receipt (
296+ receipt : Mapping [str , str ] | None ,
297+ ) -> tuple [str , str ]:
298+ if receipt is None :
299+ return "pending" , "target_execution_evidence_missing"
300+ outcome = receipt ["outcome" ]
301+ if outcome == "reconciliation_required" :
302+ return "unavailable" , "target_execution_reconciliation_required"
303+ if outcome == "failed" :
304+ return "unavailable" , "target_execution_receipt_failed"
305+ return "verified" , "target_execution_receipt_observed"
173306
174307
175308def _mapping (value : object , error_code : str ) -> Mapping [str , Any ]:
@@ -199,6 +332,44 @@ def _report_timestamp(report: Mapping[str, Any]) -> datetime:
199332 raise ExecutionEvidenceProjectionError ("runtime_report_timestamp_invalid" )
200333
201334
335+ def _receipt_timestamp (value : object ) -> datetime :
336+ if not isinstance (value , str ) or not value .strip ():
337+ raise ExecutionEvidenceProjectionError ("runtime_report_execution_receipt_invalid" )
338+ try :
339+ parsed = datetime .fromisoformat (value .strip ().replace ("Z" , "+00:00" ))
340+ except ValueError as exc :
341+ raise ExecutionEvidenceProjectionError ("runtime_report_execution_receipt_invalid" ) from exc
342+ if parsed .tzinfo is None or parsed .utcoffset () is None :
343+ raise ExecutionEvidenceProjectionError ("runtime_report_execution_receipt_invalid" )
344+ return parsed .astimezone (UTC ).replace (microsecond = 0 )
345+
346+
347+ def _execution_receipt_id (
348+ * ,
349+ platform : str ,
350+ strategy_profile : str ,
351+ strategy_revision : str ,
352+ execution_mode : str ,
353+ outcome : str ,
354+ broker_confirmation : str ,
355+ observed_at : str ,
356+ ) -> str :
357+ payload = {
358+ "schema_version" : EXECUTION_RECEIPT_SCHEMA_VERSION ,
359+ "platform" : platform ,
360+ "strategy_profile" : strategy_profile ,
361+ "strategy_revision" : strategy_revision ,
362+ "execution_mode" : execution_mode ,
363+ "outcome" : outcome ,
364+ "broker_confirmation" : broker_confirmation ,
365+ "observed_at" : observed_at ,
366+ }
367+ digest = hashlib .sha256 (
368+ json .dumps (payload , sort_keys = True , separators = ("," , ":" ), ensure_ascii = True ).encode ("utf-8" )
369+ ).hexdigest ()
370+ return f"execution-receipt.{ digest [:32 ]} "
371+
372+
202373def _deployment_id (
203374 * ,
204375 platform : str ,
0 commit comments