39 lines
22 KiB
JSON
39 lines
22 KiB
JSON
{
|
|
"schema_version": 1,
|
|
"channel": "homelab-runtime",
|
|
"command_id": "SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2",
|
|
"status": "OK",
|
|
"rc": 0,
|
|
"host": "pve01",
|
|
"mode": "read-only",
|
|
"component": "signalbot-semantic-conflict-identity-rca",
|
|
"started_at_utc": "2026-09-21T06:26:30Z",
|
|
"finished_at_utc": "2026-09-21T06:26:33Z",
|
|
"reference_register_checked": true,
|
|
"reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66",
|
|
"error_register_checked": true,
|
|
"error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0",
|
|
"command_sha256": "cdd4ca3200241b36187999fff08989c1a1e93b90c6e990ea45f78e300444f86f",
|
|
"duplicate_failed_command_blocked": false,
|
|
"block_reason": null,
|
|
"execution_started": true,
|
|
"change_declared": false,
|
|
"result_contract_valid": true,
|
|
"result_contract_status": null,
|
|
"result_contract_error": null,
|
|
"command_rc": 0,
|
|
"changes_made": false,
|
|
"rollback_started": false,
|
|
"rollback_restored": null,
|
|
"mutation_outcome": "NO_MUTATION",
|
|
"sanitized": true,
|
|
"secrets_included": false,
|
|
"private_addresses_included": false,
|
|
"raw_evidence_retained_locally": true,
|
|
"raw_evidence_sha256": "96171914aa4f0df906f4a8d604c4ea16e0fe43b7634b08abc0b7596ab1f9940e",
|
|
"sanitized_output_sha256": "96171914aa4f0df906f4a8d604c4ea16e0fe43b7634b08abc0b7596ab1f9940e",
|
|
"output_truncated_in_json": false,
|
|
"full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt",
|
|
"output": "SIGNALBOT052SEM2_RESULT={\"outer_rc\":0,\"guest_exitcode\":0,\"rca\":{\"ok\":true,\"target_seqs\":[251009,318578,350488,377008],\"conflict_count\":4,\"conflict_identities\":[\"102515c73c5748a56ca153cab57cdb832b5aae503a5485a23265c6313699d80f\",\"4864b1515a46c5a7027df34865751263f136132b186a22a85bedf56d5b3c8580\",\"ac5ee89769b01055080a1ef6b66a3bf2a0ee49841730f551293552af57e61809\",\"ff901a1b6bc9a49c961c34d90731fd1550fd89e00ded60ca892b2e2d5fb33363\"],\"results\":[{\"seq\":251009,\"result\":{\"window_id\":\"9cef91126f4f0043718d71b90d627540355d1f0f0f1fd75ee30f9bef3379ad88\",\"reconnect_event_seq\":251009,\"reconnect_received_at\":\"2026-09-19 08:56:37.306311+00:00\",\"previous_trade_identity\":\"ac5ee89769b01055080a1ef6b66a3bf2a0ee49841730f551293552af57e61809\",\"previous_trade_mts\":\"2026-09-19 08:56:34.170000+00:00\",\"next_trade_identity\":\"cac1c294e6e6f358f8cb8151ecb7ca573b64f9a116d8cab2f0db588df7d83dc7\",\"next_trade_mts\":\"2026-09-19 08:56:43.071000+00:00\",\"status\":\"UNRESOLVED\",\"evidence_sha256\":\"bdf2ac6ab74275846073a4813fef5f4cc409190a8444dd7e47d9283fa5736ec2\",\"recovered_row_count\":0,\"failure_reason\":\"REST_SEMANTIC_CONFLICT\",\"created_at\":\"2026-09-19 08:56:43.166296+00:00\",\"resolved_at\":\"2026-09-21 06:26:32.078542+00:00\"},\"conflicts\":[{\"trade_identity\":\"ac5ee89769b01055080a1ef6b66a3bf2a0ee49841730f551293552af57e61809\",\"local_semantic_hash\":\"a68332effcadf8a928ead478507829fe5b1a3eb2bf9a09f4200a5cdf814c0e12\",\"rest_semantic_hash\":\"1fec66432d52f6803021ac880cc44ce7ddc66e3a573398c9d97e267addee1d32\",\"rest_trade\":{\"trade_identity\":\"ac5ee89769b01055080a1ef6b66a3bf2a0ee49841730f551293552af57e61809\",\"semantic_hash\":\"1fec66432d52f6803021ac880cc44ce7ddc66e3a573398c9d97e267addee1d32\",\"trade_id\":1978047385,\"mts\":\"2026-09-19 08:56:34.171000+00:00\",\"amount\":\"0.00211007\",\"price\":\"81294\",\"source_payload_hash\":\"7ce688662cd8629a8a14ecf30c644aa46aabfa9613d665aa1c7b8ef40208e9ae\"}}]},{\"seq\":318578,\"result\":{\"window_id\":\"f3342e8836aa6f1a655a977e6839647e8f305cb90ce4a1977c417f9541a0ecda\",\"reconnect_event_seq\":318578,\"reconnect_received_at\":\"2026-09-20 01:19:10.585588+00:00\",\"previous_trade_identity\":\"4d902cf30ae01b151d21f3ecd1b706af0a7f87c9c44995b381e0e064b2f236b3\",\"previous_trade_mts\":\"2026-09-20 01:19:03.365000+00:00\",\"next_trade_identity\":\"bd6ae492eca899f8710d0c4b88704cb5a0a34ff94a23419249366f4ebd3586b6\",\"next_trade_mts\":\"2026-09-20 01:19:16.432000+00:00\",\"status\":\"UNRESOLVED\",\"evidence_sha256\":\"1a60ffa68cbe5415f4e55b64a97803128ba79eb7b730d84cac69a364f597bc63\",\"recovered_row_count\":0,\"failure_reason\":\"REST_SEMANTIC_CONFLICT\",\"created_at\":\"2026-09-20 01:19:16.494983+00:00\",\"resolved_at\":\"2026-09-21 06:26:32.467957+00:00\"},\"conflicts\":[{\"trade_identity\":\"4864b1515a46c5a7027df34865751263f136132b186a22a85bedf56d5b3c8580\",\"local_semantic_hash\":\"0bd2f70ee53f0e68ce3250a9db186bb78289ef3335e6843b3298708d26a90946\",\"rest_semantic_hash\":\"449f362d057b4c1d5872e5c592a81540d2dab554dc5424845896247f00761400\",\"rest_trade\":{\"trade_identity\":\"4864b1515a46c5a7027df34865751263f136132b186a22a85bedf56d5b3c8580\",\"semantic_hash\":\"449f362d057b4c1d5872e5c592a81540d2dab554dc5424845896247f00761400\",\"trade_id\":1978425230,\"mts\":\"2026-09-20 01:19:16.431000+00:00\",\"amount\":\"0.0002\",\"price\":\"81144\",\"source_payload_hash\":\"53e0f9604d7422f6bb0cf507ef71da60a62f27df87e2d93e330fa5991c48e8a2\"}}]},{\"seq\":350488,\"result\":{\"window_id\":\"f429abc398b54cb0cbd869dce8c0be4e8c8ff8fb5ec7bb1a345c3bc8c7a394fb\",\"reconnect_event_seq\":350488,\"reconnect_received_at\":\"2026-09-20 07:26:44.462330+00:00\",\"previous_trade_identity\":\"25ae8d55a395d0a39001b1c409a86130c78b7221d31bdefc80242fc7af49da60\",\"previous_trade_mts\":\"2026-09-20 07:26:42.303000+00:00\",\"next_trade_identity\":\"15a77ac49619bc44a15ab3cb04219963639c612347f0de2ba82bf482c59a6b61\",\"next_trade_mts\":\"2026-09-20 07:26:46.404000+00:00\",\"status\":\"UNRESOLVED\",\"evidence_sha256\":\"a3502d8e6d42f5e6b4febee02f36cf8e6abac43c8730db0a56e8721fed5ff04e\",\"recovered_row_count\":0,\"failure_reason\":\"REST_SEMANTIC_CONFLICT\",\"created_at\":\"2026-09-20 07:26:46.505770+00:00\",\"resolved_at\":\"2026-09-21 06:26:32.629075+00:00\"},\"conflicts\":[{\"trade_identity\":\"ff901a1b6bc9a49c961c34d90731fd1550fd89e00ded60ca892b2e2d5fb33363\",\"local_semantic_hash\":\"ef5d24518812bce987bd8dc7f8401d18e85fac4403bde28798e09df7bb76110f\",\"rest_semantic_hash\":\"b52ddcf353996786e3b60a3594cf28602d884074d94b995f88b7d573707000b9\",\"rest_trade\":{\"trade_identity\":\"ff901a1b6bc9a49c961c34d90731fd1550fd89e00ded60ca892b2e2d5fb33363\",\"semantic_hash\":\"b52ddcf353996786e3b60a3594cf28602d884074d94b995f88b7d573707000b9\",\"trade_id\":1978544807,\"mts\":\"2026-09-20 07:26:42.304000+00:00\",\"amount\":\"0.00007465\",\"price\":\"80374\",\"source_payload_hash\":\"8763bfa6192a0bf44d9bfaa4cde01abe95bc39c53954247d2970dfcceb0d979f\"}}]},{\"seq\":377008,\"result\":{\"window_id\":\"7ba6b9d6bfcc433411890610b9d1282178a9646d61d026798b82f51a4985ccdc\",\"reconnect_event_seq\":377008,\"reconnect_received_at\":\"2026-09-20 13:53:16.325492+00:00\",\"previous_trade_identity\":\"102515c73c5748a56ca153cab57cdb832b5aae503a5485a23265c6313699d80f\",\"previous_trade_mts\":\"2026-09-20 13:52:37.772000+00:00\",\"next_trade_identity\":\"7782961f0ddf1bd08bdd9a1e311da68898b133f65fea2e24698fd9612e52a008\",\"next_trade_mts\":\"2026-09-20 13:53:16.750000+00:00\",\"status\":\"UNRESOLVED\",\"evidence_sha256\":\"6b4ff1de113e7f0433c9de74cbb88ed1218fe256244830433f4474b106ce41ef\",\"recovered_row_count\":0,\"failure_reason\":\"REST_SEMANTIC_CONFLICT\",\"created_at\":\"2026-09-20 13:53:16.842477+00:00\",\"resolved_at\":\"2026-09-21 06:26:32.769726+00:00\"},\"conflicts\":[{\"trade_identity\":\"102515c73c5748a56ca153cab57cdb832b5aae503a5485a23265c6313699d80f\",\"local_semantic_hash\":\"3882f08ebf2ef5777383f6ce57ccf3a56c5064e47eae32096c699b6fadaf14aa\",\"rest_semantic_hash\":\"0db8672a6d0b8425a4e3cd9a3ddb6ec48c179613be302f27b9237d17f251693b\",\"rest_trade\":{\"trade_identity\":\"102515c73c5748a56ca153cab57cdb832b5aae503a5485a23265c6313699d80f\",\"semantic_hash\":\"0db8672a6d0b8425a4e3cd9a3ddb6ec48c179613be302f27b9237d17f251693b\",\"trade_id\":1978663377,\"mts\":\"2026-09-20 13:52:37.773000+00:00\",\"amount\":\"-0.00040192\",\"price\":\"80573\",\"source_payload_hash\":\"4ee54a973defc37cefd51a348baaad298f4da43f6de89313e16478df82ae44a3\"}}]}],\"local_rows\":{\"trade_receipts\":[{\"trade_identity\":\"102515c73c5748a56ca153cab57cdb832b5aae503a5485a23265c6313699d80f\",\"semantic_hash\":\"3882f08ebf2ef5777383f6ce57ccf3a56c5064e47eae32096c699b6fadaf14aa\",\"receipt_id\":\"4f898c0c713eb05514d1bd44985adfe4eb5f3a961d9fada6688a4bbbc8cdfea7\"},{\"trade_identity\":\"4864b1515a46c5a7027df34865751263f136132b186a22a85bedf56d5b3c8580\",\"semantic_hash\":\"0bd2f70ee53f0e68ce3250a9db186bb78289ef3335e6843b3298708d26a90946\",\"receipt_id\":\"788074a38ac08db3eb6cd831b33bf7c1acb577c7ebd5eed8d8d2a40dffd67db4\"},{\"trade_identity\":\"ac5ee89769b01055080a1ef6b66a3bf2a0ee49841730f551293552af57e61809\",\"semantic_hash\":\"a68332effcadf8a928ead478507829fe5b1a3eb2bf9a09f4200a5cdf814c0e12\",\"receipt_id\":\"d5dfd3a648ea3daefbd8f8e5c7aaede7aa96350afdaa3e7e92007a902494307e\"},{\"trade_identity\":\"ff901a1b6bc9a49c961c34d90731fd1550fd89e00ded60ca892b2e2d5fb33363\",\"semantic_hash\":\"ef5d24518812bce987bd8dc7f8401d18e85fac4403bde28798e09df7bb76110f\",\"receipt_id\":\"d00c3918ac73194f1cb28e91b901e912659ad0aba6357e324677034c1e2dd808\"}],\"trade_revisions\":[{\"revision_seq\":180316,\"trade_identity\":\"102515c73c5748a56ca153cab57cdb832b5aae503a5485a23265c6313699d80f\",\"semantic_hash\":\"3882f08ebf2ef5777383f6ce57ccf3a56c5064e47eae32096c699b6fadaf14aa\",\"trade_id\":1978663377,\"mts\":\"2026-09-20T13:52:37.772000+00:00\",\"amount\":\"-0.00040192\",\"price\":\"80573\",\"source_payload_hash\":\"6799fb8d397f192d51de2148e6583013ff8ad845aa1c734cc41be3170dc05bd0\",\"receipt_id\":\"4f898c0c713eb05514d1bd44985adfe4eb5f3a961d9fada6688a4bbbc8cdfea7\",\"trade_json\":\"{\\\"amount\\\":\\\"-0.00040192\\\",\\\"mts\\\":\\\"2026-09-20T13:52:37.772000+00:00\\\",\\\"price\\\":\\\"80573\\\",\\\"semantic_hash\\\":\\\"3882f08ebf2ef5777383f6ce57ccf3a56c5064e47eae32096c699b6fadaf14aa\\\",\\\"source_payload_hash\\\":\\\"6799fb8d397f192d51de2148e6583013ff8ad845aa1c734cc41be3170dc05bd0\\\",\\\"trade_id\\\":1978663377,\\\"trade_identity\\\":\\\"102515c73c5748a56ca153cab57cdb832b5aae503a5485a23265c6313699d80f\\\"}\"},{\"revision_seq\":152612,\"trade_identity\":\"4864b1515a46c5a7027df34865751263f136132b186a22a85bedf56d5b3c8580\",\"semantic_hash\":\"0bd2f70ee53f0e68ce3250a9db186bb78289ef3335e6843b3298708d26a90946\",\"trade_id\":1978425230,\"mts\":\"2026-09-20T01:19:16.430000+00:00\",\"amount\":\"0.0002\",\"price\":\"81144\",\"source_payload_hash\":\"01c9ec301dba6ddbf3cb15ee66a1b5d2258ba173dd88c51c7ae5e5d621740e1c\",\"receipt_id\":\"788074a38ac08db3eb6cd831b33bf7c1acb577c7ebd5eed8d8d2a40dffd67db4\",\"trade_json\":\"{\\\"amount\\\":\\\"0.0002\\\",\\\"mts\\\":\\\"2026-09-20T01:19:16.430000+00:00\\\",\\\"price\\\":\\\"81144\\\",\\\"semantic_hash\\\":\\\"0bd2f70ee53f0e68ce3250a9db186bb78289ef3335e6843b3298708d26a90946\\\",\\\"source_payload_hash\\\":\\\"01c9ec301dba6ddbf3cb15ee66a1b5d2258ba173dd88c51c7ae5e5d621740e1c\\\",\\\"trade_id\\\":1978425230,\\\"trade_identity\\\":\\\"4864b1515a46c5a7027df34865751263f136132b186a22a85bedf56d5b3c8580\\\"}\"},{\"revision_seq\":120788,\"trade_identity\":\"ac5ee89769b01055080a1ef6b66a3bf2a0ee49841730f551293552af57e61809\",\"semantic_hash\":\"a68332effcadf8a928ead478507829fe5b1a3eb2bf9a09f4200a5cdf814c0e12\",\"trade_id\":1978047385,\"mts\":\"2026-09-19T08:56:34.170000+00:00\",\"amount\":\"0.00211007\",\"price\":\"81294\",\"source_payload_hash\":\"dda5100ed2618f87b31bfa1306bed3d25de0c358d8a5cb059547f58c60804603\",\"receipt_id\":\"d5dfd3a648ea3daefbd8f8e5c7aaede7aa96350afdaa3e7e92007a902494307e\",\"trade_json\":\"{\\\"amount\\\":\\\"0.00211007\\\",\\\"mts\\\":\\\"2026-09-19T08:56:34.170000+00:00\\\",\\\"price\\\":\\\"81294\\\",\\\"semantic_hash\\\":\\\"a68332effcadf8a928ead478507829fe5b1a3eb2bf9a09f4200a5cdf814c0e12\\\",\\\"source_payload_hash\\\":\\\"dda5100ed2618f87b31bfa1306bed3d25de0c358d8a5cb059547f58c60804603\\\",\\\"trade_id\\\":1978047385,\\\"trade_identity\\\":\\\"ac5ee89769b01055080a1ef6b66a3bf2a0ee49841730f551293552af57e61809\\\"}\"},{\"revision_seq\":167827,\"trade_identity\":\"ff901a1b6bc9a49c961c34d90731fd1550fd89e00ded60ca892b2e2d5fb33363\",\"semantic_hash\":\"ef5d24518812bce987bd8dc7f8401d18e85fac4403bde28798e09df7bb76110f\",\"trade_id\":1978544807,\"mts\":\"2026-09-20T07:26:42.303000+00:00\",\"amount\":\"0.00007465\",\"price\":\"80374\",\"source_payload_hash\":\"3408edf5ee86d62afb50c5d01ea09cd734eae97dabc39aa9229a158aab0e4f2f\",\"receipt_id\":\"d00c3918ac73194f1cb28e91b901e912659ad0aba6357e324677034c1e2dd808\",\"trade_json\":\"{\\\"amount\\\":\\\"0.00007465\\\",\\\"mts\\\":\\\"2026-09-20T07:26:42.303000+00:00\\\",\\\"price\\\":\\\"80374\\\",\\\"semantic_hash\\\":\\\"ef5d24518812bce987bd8dc7f8401d18e85fac4403bde28798e09df7bb76110f\\\",\\\"source_payload_hash\\\":\\\"3408edf5ee86d62afb50c5d01ea09cd734eae97dabc39aa9229a158aab0e4f2f\\\",\\\"trade_id\\\":1978544807,\\\"trade_identity\\\":\\\"ff901a1b6bc9a49c961c34d90731fd1550fd89e00ded60ca892b2e2d5fb33363\\\"}\"}]},\"source_methods\":{\"fetch_trade_window\":\" def fetch_trade_window(\\n self,\\n symbol: str,\\n *,\\n start_mts: datetime,\\n end_mts: datetime,\\n ) -> BitfinexTradeHistoryBatch:\\n if not isinstance(symbol, str) or not symbol.startswith(\\\"t\\\") or len(symbol) < 2:\\n raise DemonovError(\\\"Bitfinex trade history symbol invalid\\\")\\n start_mts = _utc(start_mts, \\\"start_mts\\\")\\n end_mts = _utc(end_mts, \\\"end_mts\\\")\\n if end_mts < start_mts:\\n raise DemonovError(\\\"Bitfinex trade history interval invalid\\\")\\n start_ms = int(start_mts.timestamp() * 1000)\\n end_ms = int(end_mts.timestamp() * 1000)\\n query = urlencode({\\\"start\\\": start_ms, \\\"end\\\": end_ms, \\\"sort\\\": 1, \\\"limit\\\": BITFINEX_PUBLIC_HISTORY_LIMIT})\\n url = f\\\"{BITFINEX_PUBLIC_TRADES_BASE}/{quote(symbol, safe='')}/hist?{query}\\\"\\n try:\\n payload = self._fetch_json(\\n url,\\n timeout=self.timeout,\\n max_bytes=self.max_bytes,\\n )\\n except DemonovError:\\n raise\\n except Exception as exc:\\n raise DemonovError(\\n \\\"Bitfinex public trade history request failed\\\"\\n ) from exc\\n if not isinstance(payload, list):\\n raise DemonovError(\\\"Bitfinex public trade history payload invalid\\\")\\n\\n normalized: list[BitfinexCanonicalTradeV1] = []\\n raw_rows: list[list[object]] = []\\n seen: dict[str, str] = {}\\n order_keys: list[tuple[datetime, int]] = []\\n for raw in payload:\\n if not isinstance(raw, list):\\n raise DemonovError(\\\"Bitfinex REST trade row malformed\\\")\\n trade = normalize_bitfinex_rest_trade(raw)\\n raw_rows.append(list(raw[:4]))\\n prior = seen.get(trade.trade_identity)\\n if prior is not None:\\n if prior != trade.semantic_hash:\\n raise DemonovError(\\\"Bitfinex REST trade semantic conflict\\\")\\n continue\\n seen[trade.trade_identity] = trade.semantic_hash\\n normalized.append(trade)\\n order_keys.append((trade.mts, trade.trade_id))\\n if order_keys != sorted(order_keys):\\n normalized.sort(key=lambda trade: (trade.mts, trade.trade_id))\\n\\n evidence_sha256 = canonical_hash(\\n {\\n \\\"schema\\\": \\\"CR0116_BITFINEX_RECONCILIATION_REST_EVIDENCE_V1\\\",\\n \\\"symbol\\\": symbol,\\n \\\"start_mts\\\": start_mts,\\n \\\"end_mts\\\": end_mts,\\n \\\"raw_row_count\\\": len(payload),\\n \\\"rows\\\": raw_rows,\\n }\\n )\\n return BitfinexTradeHistoryBatch(\\n symbol=symbol,\\n start_mts=start_mts,\\n end_mts=end_mts,\\n raw_row_count=len(payload),\\n trades=tuple(normalized),\\n evidence_sha256=evidence_sha256,\\n )\\n\",\"reconcile_window\":\" def reconcile_window(\\n self,\\n journal,\\n window_id: str,\\n *,\\n symbol: str,\\n resolved_at: datetime,\\n ) -> ReconciliationWindow:\\n resolved_at = _utc(resolved_at, \\\"resolved_at\\\")\\n window = journal.reconciliation_window(window_id)\\n if window.status != ReconciliationStatus.PENDING:\\n return window\\n try:\\n batch = self.fetch_trade_window(\\n symbol,\\n start_mts=window.previous_trade_mts,\\n end_mts=window.next_trade_mts,\\n )\\n if batch.raw_row_count >= BITFINEX_PUBLIC_HISTORY_LIMIT:\\n return journal.mark_reconciliation_unresolved(\\n window_id,\\n evidence_sha256=batch.evidence_sha256,\\n failure_reason=\\\"REST_ROW_LIMIT_REACHED\\\",\\n resolved_at=resolved_at,\\n )\\n if not batch.trades:\\n return journal.mark_reconciliation_unresolved(\\n window_id,\\n evidence_sha256=batch.evidence_sha256,\\n failure_reason=\\\"REST_NO_FORWARD_PROOF\\\",\\n resolved_at=resolved_at,\\n )\\n\\n for trade in batch.trades:\\n existing = journal.latest_trade_semantic_hash(trade.trade_identity)\\n if existing is not None and existing != trade.semantic_hash:\\n return journal.mark_reconciliation_unresolved(\\n window_id,\\n evidence_sha256=batch.evidence_sha256,\\n failure_reason=\\\"REST_SEMANTIC_CONFLICT\\\",\\n resolved_at=resolved_at,\\n )\\n\\n recovered = 0\\n for index, trade in enumerate(batch.trades):\\n receipt = SourceReceiptV1.build(\\n venue_id=\\\"BITFINEX\\\",\\n source_kind=\\\"REST_TRADE_HISTORY\\\",\\n received_at=resolved_at,\\n source_sequence=index,\\n raw_payload_hash=trade.source_payload_hash,\\n collector_session_id=f\\\"reconciliation:{window_id}\\\",\\n )\\n receipt_id = journal.record_receipt(receipt)\\n result = journal.record_trade(trade, receipt_id=receipt_id)\\n if result == \\\"INSERTED\\\":\\n recovered += 1\\n elif result != \\\"DUPLICATE\\\":\\n return journal.mark_reconciliation_unresolved(\\n window_id,\\n evidence_sha256=batch.evidence_sha256,\\n failure_reason=f\\\"REST_INSERT_{result}\\\",\\n resolved_at=resolved_at,\\n )\\n\\n if not journal.has_trade_identity(window.previous_trade_identity):\\n return journal.mark_reconciliation_unresolved(\\n window_id,\\n evidence_sha256=batch.evidence_sha256,\\n failure_reason=\\\"PREVIOUS_BOUNDARY_MISSING\\\",\\n resolved_at=resolved_at,\\n )\\n if not journal.has_trade_identity(window.next_trade_identity):\\n return journal.mark_reconciliation_unresolved(\\n window_id,\\n evidence_sha256=batch.evidence_sha256,\\n failure_reason=\\\"NEXT_BOUNDARY_MISSING\\\",\\n resolved_at=resolved_at,\\n )\\n for trade in batch.trades:\\n if journal.latest_trade_semantic_hash(trade.trade_identity) != trade.semantic_hash:\\n return journal.mark_reconciliation_unresolved(\\n window_id,\\n evidence_sha256=batch.evidence_sha256,\\n failure_reason=\\\"REST_MERGE_PROOF_FAILED\\\",\\n resolved_at=resolved_at,\\n )\\n return journal.mark_reconciliation_reconciled(\\n window_id,\\n evidence_sha256=batch.evidence_sha256,\\n recovered_row_count=recovered,\\n resolved_at=resolved_at,\\n )\\n except DemonovError as exc:\\n reason = str(exc)\\n reason_hash = hashlib.sha256(reason.encode(\\\"utf-8\\\")).hexdigest()\\n return journal.mark_reconciliation_unresolved(\\n window_id,\\n evidence_sha256=reason_hash,\\n failure_reason=\\\"REST_FETCH_OR_VALIDATION_FAILED\\\",\\n resolved_at=resolved_at,\\n )\\n\",\"latest_trade_semantic_hash\":\" def latest_trade_semantic_hash(self, trade_identity: str) -> str | None:\\n row = self._db.execute(\\n \\\"\\\"\\\"\\n SELECT semantic_hash FROM trade_revisions\\n WHERE trade_identity=?\\n ORDER BY revision_seq DESC LIMIT 1\\n \\\"\\\"\\\",\\n (trade_identity,),\\n ).fetchone()\\n return None if row is None else str(row[\\\"semantic_hash\\\"])\\n\",\"normalize_bitfinex_rest_trade\":\"def normalize_bitfinex_rest_trade(row: object) -> BitfinexCanonicalTradeV1:\\n if not isinstance(row, list) or len(row) < 4:\\n raise DemonovError(\\\"Bitfinex REST trade row malformed\\\")\\n trade_id, mts_ms, amount_raw, price_raw = row[:4]\\n if not isinstance(trade_id, int) or isinstance(trade_id, bool) or trade_id <= 0:\\n raise DemonovError(\\\"Bitfinex REST trade id invalid\\\")\\n if not isinstance(mts_ms, int) or isinstance(mts_ms, bool) or mts_ms < 0:\\n raise DemonovError(\\\"Bitfinex REST trade timestamp invalid\\\")\\n try:\\n amount = Decimal(str(amount_raw))\\n price = Decimal(str(price_raw))\\n except Exception as exc:\\n raise DemonovError(\\\"Bitfinex REST trade numeric value invalid\\\") from exc\\n source_payload_hash = _source_payload_hash(\\n trade_id=trade_id,\\n mts_ms=mts_ms,\\n amount=amount,\\n price=price,\\n )\\n return BitfinexCanonicalTradeV1.build(\\n trade_id=trade_id,\\n mts=datetime.fromtimestamp(mts_ms / 1000, tz=timezone.utc),\\n amount=amount,\\n price=price,\\n source_payload_hash=source_payload_hash,\\n )\\n\"},\"copy_quick_check\":\"ok\"}}\nTASK_RESULT=PASS_SIGNALBOT_052SEM2_CONFLICT_IDENTITIES_CAPTURED\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n"
|
|
}
|