From 92cc05bbfe542b3ae33eeff52793bfc8be08ad34 Mon Sep 17 00:00:00 2001 From: homelab-runtime-publisher Date: Mon, 21 Sep 2026 06:26:34 +0000 Subject: [PATCH] runtime: publish SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2 --- ...EMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.json | 38 +++++++++++++++++++ ...SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.txt | 35 +++++++++++++++++ runtime/latest.json | 16 ++++---- runtime/latest.txt | 36 ++++-------------- 4 files changed, 89 insertions(+), 36 deletions(-) create mode 100644 runtime/history/SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.json create mode 100644 runtime/history/SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.txt diff --git a/runtime/history/SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.json b/runtime/history/SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.json new file mode 100644 index 00000000..6e45747a --- /dev/null +++ b/runtime/history/SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.json @@ -0,0 +1,38 @@ +{ + "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" +} diff --git a/runtime/history/SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.txt b/runtime/history/SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.txt new file mode 100644 index 00000000..c6bbc532 --- /dev/null +++ b/runtime/history/SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2.txt @@ -0,0 +1,35 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2 +STATUS=OK +RC=0 +HOST=pve01 +MODE=read-only +COMPONENT=signalbot-semantic-conflict-identity-rca +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 +COMMAND_SHA256=cdd4ca3200241b36187999fff08989c1a1e93b90c6e990ea45f78e300444f86f +DUPLICATE_FAILED_COMMAND_BLOCKED=false +EXECUTION_STARTED=true +CHANGE_DECLARED=false +RESULT_CONTRACT_VALID=true +RESULT_CONTRACT_STATUS=NOT_APPLICABLE +RESULT_CONTRACT_ERROR=NONE +COMMAND_RC=0 +CHANGES_MADE=false +ROLLBACK_STARTED=false +ROLLBACK_RESTORED=null +MUTATION_OUTCOME=NO_MUTATION +SANITIZED=yes +SECRETS_INCLUDED=no +PRIVATE_ADDRESSES_INCLUDED=no +RAW_EVIDENCE_SHA256=96171914aa4f0df906f4a8d604c4ea16e0fe43b7634b08abc0b7596ab1f9940e +SANITIZED_OUTPUT_SHA256=96171914aa4f0df906f4a8d604c4ea16e0fe43b7634b08abc0b7596ab1f9940e +OUTPUT_BEGIN +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"}} +TASK_RESULT=PASS_SIGNALBOT_052SEM2_CONFLICT_IDENTITIES_CAPTURED +HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index 011f7d0d..6e45747a 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,19 +1,19 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "SUPPORT-260921-HOMELAB-BACKUP-CLOUDB-PREFLIGHT-RCA-READONLY-1064R1", + "command_id": "SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2", "status": "OK", "rc": 0, "host": "pve01", "mode": "read-only", - "component": "homelab-backup-cloudb-preflight-rca", - "started_at_utc": "2026-09-21T06:26:01Z", - "finished_at_utc": "2026-09-21T06:26:05Z", + "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": "b508f92361099e24264836513bd255c236078b8a0b80039c6c69016e3bce2085", + "command_sha256": "cdd4ca3200241b36187999fff08989c1a1e93b90c6e990ea45f78e300444f86f", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, @@ -30,9 +30,9 @@ "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "a5e3e41807765a5f0bb7a13406d297e3deebf550a436821efe1df44356f9fa5c", - "sanitized_output_sha256": "a5e3e41807765a5f0bb7a13406d297e3deebf550a436821efe1df44356f9fa5c", + "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": "WORKERS2_CLOUDB_RCA_BEGIN=1\nCOMMAND_ID=SUPPORT-260921-HOMELAB-BACKUP-CLOUDB-PREFLIGHT-RCA-READONLY-1064R1\nMODE=read-only\nCOMPONENT=homelab-backup-cloudb-preflight-rca\nMUTATION_BOUNDARY=READ_ONLY_NO_REPO_WRITE_NO_SYSTEMD_ACTION_NO_BACKUP_NO_RESTORE_NO_RETENTION_NO_DELETE_NO_MAIL\nSTATE_INVENTORY={\"latest_files\":[\"app-skladchik-reports-monitor-pve01-20260921T033135Z.json\",\"app-skladchik-reports-monitor-pve01-20260916T113630Z.json\",\"app-skladchik-reports-monitor-pve01-20260915T223334Z.json\",\"app-skladchik-reports-monitor-pve01-20260915T093500Z.json\",\"app-skladchik-reports-monitor-pve01-20260914T193818Z.json\",\"app-skladchik-reports-monitor-pve01-20260914T063210Z.json\",\"app-skladchik-reports-monitor-pve01-20260913T174140Z.json\",\"app-skladchik-reports-monitor-pve01-20260913T033047Z.json\"],\"sealed\":57,\"total\":57}\nLATEST_SEALED_STATE={\"archive_sha256\":\"c41f0f9f871a6d16ae9ba98c2e40b06f9107082d6f9985dcb2e0a19c34412140\",\"archive_size_bytes\":178434,\"cloud_a_verified\":true,\"cloud_b_verified\":true,\"cloud_quorum\":2,\"generation\":\"app-skladchik-reports-monitor-pve01-20260921T033135Z\",\"local_cleanup\":\"OK\",\"local_payload_present\":false,\"logical_id\":\"app-skladchik-reports-monitor\",\"part_count\":1,\"part_hashes_verified\":true,\"parts_manifest_sha256\":\"94b2185cab444b7835946dc3fd009adc7103ac09f1f607e93b9b328dbfeccedf\",\"payload_name\":\"app-skladchik-reports-monitor-pve01-20260921T033135Z.tar.zst\",\"remote_a_base\":\"pve01-mail-01-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z\",\"remote_b_base\":\"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z\",\"schema\":\"homelab-cloud-quorum-payload-v1\",\"seal_written\":true,\"state_file\":\"app-skladchik-reports-monitor-pve01-20260921T033135Z.json\",\"state_sha256\":\"41c4e42953c36022ea4f18b5451ec70ea251c86542502444e748545ffa799271\",\"status\":\"SEALED\",\"types\":{\"archive_sha256\":\"str\",\"archive_size_bytes\":\"int\",\"cloud_a_verified\":\"bool\",\"cloud_b_verified\":\"bool\",\"cloud_quorum\":\"int\",\"generation\":\"str\",\"local_cleanup\":\"str\",\"local_payload_present\":\"bool\",\"logical_id\":\"str\",\"part_count\":\"int\",\"part_hashes_verified\":\"bool\",\"parts_manifest_sha256\":\"str\",\"payload_name\":\"str\",\"remote_a_base\":\"str\",\"remote_b_base\":\"str\",\"schema\":\"str\",\"seal_written\":\"bool\",\"status\":\"str\"}}\nSTATE_RELEVANT_KEYS=[{\"path\":\"status\",\"type\":\"str\",\"value\":\"SEALED\"},{\"path\":\"generation\",\"type\":\"str\",\"value\":\"app-skladchik-reports-monitor-pve01-20260921T033135Z\"},{\"path\":\"payload_path\",\"type\":\"str\",\"value\":\"/mnt/staging/homelab-app-cloud-quorum/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z.tar.zst\"},{\"path\":\"payload_name\",\"type\":\"str\",\"value\":\"app-skladchik-reports-monitor-pve01-20260921T033135Z.tar.zst\"},{\"path\":\"archive_size_bytes\",\"type\":\"int\",\"value\":178434},{\"path\":\"archive_sha256\",\"type\":\"str\",\"value\":\"c41f0f9f871a6d16ae9ba98c2e40b06f9107082d6f9985dcb2e0a19c34412140\"},{\"path\":\"part_count\",\"type\":\"int\",\"value\":1},{\"path\":\"remote_a_root\",\"type\":\"str\",\"value\":\"pve01-mail-01-crypt:homelab-backups\"},{\"path\":\"remote_b_root\",\"type\":\"str\",\"value\":\"pve01-mail-02-crypt:homelab-backups\"},{\"path\":\"remote_a_base\",\"type\":\"str\",\"value\":\"pve01-mail-01-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z\"},{\"path\":\"remote_b_base\",\"type\":\"str\",\"value\":\"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z\"},{\"path\":\"cloud_a_verified\",\"type\":\"bool\",\"value\":true},{\"path\":\"cloud_b_verified\",\"type\":\"bool\",\"value\":true},{\"path\":\"cloud_a_reconstructed_sha256\",\"type\":\"str\",\"value\":\"c41f0f9f871a6d16ae9ba98c2e40b06f9107082d6f9985dcb2e0a19c34412140\"},{\"path\":\"cloud_b_reconstructed_sha256\",\"type\":\"str\",\"value\":\"c41f0f9f871a6d16ae9ba98c2e40b06f9107082d6f9985dcb2e0a19c34412140\"},{\"path\":\"cloud_a_verified_at_utc\",\"type\":\"str\",\"value\":\"2026-09-21T03:31:38Z\"},{\"path\":\"cloud_b_verified_at_utc\",\"type\":\"str\",\"value\":\"2026-09-21T03:31:43Z\"},{\"path\":\"cloud_quorum\",\"type\":\"int\",\"value\":2},{\"path\":\"part_hashes_verified\",\"type\":\"bool\",\"value\":true},{\"path\":\"parts_manifest_sha256\",\"type\":\"str\",\"value\":\"94b2185cab444b7835946dc3fd009adc7103ac09f1f607e93b9b328dbfeccedf\"},{\"path\":\"local_payload_present\",\"type\":\"bool\",\"value\":false},{\"path\":\"cloud_a_seal_verified\",\"type\":\"bool\",\"value\":true},{\"path\":\"cloud_b_seal_verified\",\"type\":\"bool\",\"value\":true},{\"path\":\"cloud_a_seal_verified_at_utc\",\"type\":\"str\",\"value\":\"2026-09-21T03:31:48Z\"},{\"path\":\"cloud_b_seal_verified_at_utc\",\"type\":\"str\",\"value\":\"2026-09-21T03:31:48Z\"}]\nCLOUDB_STRING_CANDIDATES=[{\"path\":\"remote_b_root\",\"value\":\"pve01-mail-02-crypt:homelab-backups\"},{\"path\":\"remote_b_base\",\"value\":\"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z\"}]\nRESTORE_EVIDENCE={\"exists\":true,\"file\":\"app-skladchik-reports-monitor-pve01-20260921T033135Z.json\",\"restore_source\":\"Cloud A\",\"result\":\"OK\"}\nCLOUDB_REMOTE_CHECKS=[{\"base\":\"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z\",\"lsf_rc\":0,\"manifest_candidates\":[{\"bytes\":99,\"matches_state_count\":true,\"matches_state_manifest_sha\":true,\"matches_state_size\":true,\"path\":\"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z/PARTS.tsv\",\"rc\":0,\"rows\":1,\"sha256\":\"94b2185cab444b7835946dc3fd009adc7103ac09f1f607e93b9b328dbfeccedf\",\"total_size\":178434},{\"bytes\":0,\"path\":\"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z.parts/PARTS.tsv\",\"rc\":3},{\"bytes\":0,\"path\":\"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z/parts/PARTS.tsv\",\"rc\":3}],\"source\":\"remote_b_base\",\"top_names\":[\"PARTS.tsv\",\"payload.parts/\",\"seal.json\"]},{\"base\":\"pve01-mail-02-crypt:homelab-backups\",\"lsf_rc\":0,\"manifest_candidates\":[{\"bytes\":0,\"path\":\"pve01-mail-02-crypt:homelab-backups/PARTS.tsv\",\"rc\":3},{\"bytes\":0,\"path\":\"pve01-mail-02-crypt:homelab-backups.parts/PARTS.tsv\",\"rc\":3},{\"bytes\":0,\"path\":\"pve01-mail-02-crypt:homelab-backups/parts/PARTS.tsv\",\"rc\":3}],\"source\":\"remote_b_root\",\"top_names\":[\"app-filebrowser/\",\"app-hbarhub/\",\"app-immich/\",\"app-memos/\",\"app-scrutiny/\",\"app-skladchik-moderator-assistant/\",\"app-skladchik-reports-monitor/\",\"control-bootstrap/\",\"control-bootstrap-v2/\",\"hb/\",\"pve01/\",\"retention-canary/\",\"vm110/\",\"vm111/\",\"vm112/\",\"vm113/\",\"vm130/\",\"vm150/\",\"vm160/\",\"vm170/\",\"vm171/\",\"vm180/\",\"vm190/\",\"vm200/\",\"vm211/\",\"vm9130/\"]}]\nRCA_CLASSIFICATION={\"fix\":\"REUSE_PROVEN_STATE_AND_MANIFEST_LAYOUT_WITH_CORRECTED_PREFLIGHT\",\"root_cause\":\"CLOUDB_PREFLIGHT_IMPLEMENTATION_BUG\"}\nTRANSPORT_SOURCE_FILES=[\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"/usr/local/sbin/homelab-control-backup\",\"/usr/local/sbin/homelab-rotating-boot-drill\",\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker\",\"/usr/local/libexec/homelab-app-cloud-quorum-worker\"]\nTRANSPORT_SOURCE_HITS=[{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"line\":\"31: if not isinstance(obj.get(\\\"archive_size_bytes\\\"),int) or obj[\\\"archive_size_bytes\\\"] <= 0: return False\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"line\":\"32: if not isinstance(obj.get(\\\"part_count\\\"),int) or obj[\\\"part_count\\\"] <= 0: return False\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"line\":\"34: if not isinstance(obj.get(\\\"parts_manifest_sha256\\\"),str) or not HEX64.fullmatch(obj[\\\"parts_manifest_sha256\\\"]): return False\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"line\":\"42: if obj.get(\\\"remote_a_base\\\") != expect_a or obj.get(\\\"remote_b_base\\\") != expect_b: return False\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"line\":\"84: \\\"archive_size_bytes\\\":obj[\\\"archive_size_bytes\\\"],\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"line\":\"86: \\\"parts_manifest_sha256\\\":obj[\\\"parts_manifest_sha256\\\"],\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"line\":\"87: \\\"part_count\\\":obj[\\\"part_count\\\"],\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill-state-export\",\"line\":\"89: \\\"remote_b_base\\\":obj[\\\"remote_b_base\\\"],\"},{\"file\":\"/usr/local/sbin/homelab-control-backup\",\"line\":\"72: expected_manifest=\\\"$(jq -er '.parts_manifest_sha256' \\\"$state\\\")\\\"; expected_archive=\\\"$(jq -er '.archive_sha256' \\\"$state\\\")\\\"\"},{\"file\":\"/usr/local/sbin/homelab-control-backup\",\"line\":\"73: manifest=\\\"${out}.PARTS.tsv\\\"; : >\\\"$out\\\"\"},{\"file\":\"/usr/local/sbin/homelab-control-backup\",\"line\":\"74: rclone --config \\\"$cfg\\\" cat \\\"${base%/}/PARTS.tsv\\\" >\\\"$manifest\\\" || die \\\"REMOTE_${label}_MANIFEST_READ_FAILED\\\" 74\"},{\"file\":\"/usr/local/sbin/homelab-control-backup\",\"line\":\"96: base_a=\\\"$(jq -er '.remote_a_base' \\\"$state\\\")\\\"; base_b=\\\"$(jq -er '.remote_b_base' \\\"$state\\\")\\\"; a=\\\"$work/A.tar.gz\\\"; b=\\\"$work/B.tar.gz\\\"\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"374: base=info[\\\"remote_a_base\\\"] if cloud==\\\"A\\\" else info[\\\"remote_b_base\\\"]\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"376: manifest_bytes=rclone_cat(base.rstrip(\\\"/\\\")+\\\"/PARTS.tsv\\\",60)\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"382: \\\"archive_size_bytes\\\":info[\\\"archive_size_bytes\\\"],\\\"archive_sha256\\\":info[\\\"archive_sha256\\\"],\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"383: \\\"part_count\\\":info[\\\"part_count\\\"],\\\"parts_manifest_sha256\\\":info[\\\"parts_manifest_sha256\\\"],\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"388: if hashlib.sha256(manifest_bytes).hexdigest()!=info[\\\"parts_manifest_sha256\\\"]: die(\\\"REMOTE_MANIFEST_SHA_MISMATCH_\\\"+info[\\\"vmid\\\"],66)\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"389: rows=parse_manifest(manifest_bytes,info[\\\"part_count\\\"],info[\\\"archive_size_bytes\\\"])\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"420: need_stage=qinfo[\\\"archive_size_bytes\\\"]+linfo[\\\"archive_size_bytes\\\"]+p[\\\"minimum_stage_headroom_bytes\\\"]\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"438: \\\"qemu_archive_bytes\\\":qi[\\\"archive_size_bytes\\\"],\\\"lxc_archive_bytes\\\":li[\\\"archive_size_bytes\\\"],\"},{\"file\":\"/usr/local/sbin/homelab-rotating-boot-drill\",\"line\":\"583: if total!=info[\\\"archive_size_bytes\\\"] or h.hexdigest()!=info[\\\"archive_sha256\\\"]: die(\\\"ARCHIVE_VERIFY_FAILED_\\\"+info[\\\"vmid\\\"],70)\"},{\"file\":\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"line\":\"31: if not isinstance(obj.get(\\\"archive_size_bytes\\\"),int) or obj[\\\"archive_size_bytes\\\"] <= 0: return False\"},{\"file\":\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"line\":\"32: if not isinstance(obj.get(\\\"part_count\\\"),int) or obj[\\\"part_count\\\"] <= 0: return False\"},{\"file\":\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"line\":\"34: if not isinstance(obj.get(\\\"parts_manifest_sha256\\\"),str) or not HEX64.fullmatch(obj[\\\"parts_manifest_sha256\\\"]): return False\"},{\"file\":\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"line\":\"42: if obj.get(\\\"remote_a_base\\\") != expect_a or obj.get(\\\"remote_b_base\\\") != expect_b: return False\"},{\"file\":\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"line\":\"84: \\\"archive_size_bytes\\\":obj[\\\"archive_size_bytes\\\"],\"},{\"file\":\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"line\":\"86: \\\"parts_manifest_sha256\\\":obj[\\\"parts_manifest_sha256\\\"],\"},{\"file\":\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"line\":\"87: \\\"part_count\\\":obj[\\\"part_count\\\"],\"},{\"file\":\"/usr/local/libexec/homelab-rotating-boot-drill-state-export\",\"line\":\"89: \\\"remote_b_base\\\":obj[\\\"remote_b_base\\\"],\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"198: --arg remote_b_base \\\"$REMOTE_B_BASE\\\" \\\\\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"201: --argjson part_count \\\"$PART_COUNT\\\" \\\\\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"205: archive_size_bytes:$payload_size,archive_sha256:$payload_sha,\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"206: chunk_size_bytes:$chunk_size,part_count:$part_count,\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"208: remote_a_base:$remote_a_base,remote_b_base:$remote_b_base,\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"212: cloud_quorum:0,part_hashes_verified:false,parts_manifest_sha256:null,\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"230: --arg remote_b_base \\\"$REMOTE_B_BASE\\\" \\\\\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"232: --argjson part_count \\\"$PART_COUNT\\\" \\\\\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"235: .archive_size_bytes==$payload_size and\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"237: .part_count==$part_count and\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"239: .remote_b_base==$remote_b_base' \\\\\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"248: PAYLOAD_SIZE=\\\"$(jq -er '.archive_size_bytes | numbers | select(.>0 and floor==.)' \\\"$STATE_FILE\\\")\\\" || die \\\"STATE_PAYLOAD_SIZE_INVALID\\\" 65\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"249: PART_COUNT=\\\"$(jq -er '.part_count | numbers | select(.>0 and floor==.)' \\\"$STATE_FILE\\\")\\\" || die \\\"STATE_PART_COUNT_INVALID\\\" 65\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"452: .parts_manifest_sha256=$manifest_sha' \\\\\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"463: saved_manifest=\\\"$(jq -er '.parts_manifest_sha256 | strings | select(test(\\\"^[0-9a-f]{64}$\\\"))' \\\"$STATE_FILE\\\")\\\" || die \\\"STATE_PARTS_MANIFEST_SHA_INVALID\\\" 65\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"535: .parts_manifest_sha256==null\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"540: (.parts_manifest_sha256 |\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"560:PARTS_MANIFEST=\\\"$WORK/PARTS.tsv\\\"\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"636: printf '%s\\\\n' \\\"${base%/}/PARTS.tsv\\\"\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"687: PARTS_MANIFEST_SHA=\\\"$(jq -er '.parts_manifest_sha256 | strings | select(test(\\\"^[0-9a-f]{64}$\\\"))' \\\"$STATE_FILE\\\")\\\" || die \\\"STATE_PARTS_MANIFEST_SHA_INVALID\\\" 65\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"700: remote_manifest=\\\"$WORK/remote-${label}-PARTS.tsv\\\"\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"836: archive_size_bytes:.archive_size_bytes,\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"839: part_count:.part_count,\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"840: parts_manifest_sha256:.parts_manifest_sha256,\"},{\"file\":\"/usr/local/libexec/homelab-cloud-quorum-payload\",\"line\":\"856: (.parts_manifest_sha256|type==\\\"string\\\" and test(\\\"^[0-9a-f]{64}$\\\")) and\"},{\"file\":\"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker\",\"line\":\"89: base=\\\"$(jq -er '.remote_a_base' \\\"$state\\\")\\\"; expected_msha=\\\"$(jq -er '.parts_manifest_sha256' \\\"$state\\\")\\\"; expected_count=\\\"$(jq -er '.part_count' \\\"$state\\\")\\\"; expected_size=\\\"$(jq -er '.archive_size_bytes' \\\"$state\\\")\\\"\"},{\"file\":\"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker\",\"line\":\"91: manifest=\\\"$work/PARTS.tsv\\\"; rclone cat \\\"${base%/}/PARTS.tsv\\\" >\\\"$manifest\\\"\"},{\"file\":\"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker\",\"line\":\"121: payload_name=\\\"$(jq -er '.payload_name' \\\"$state\\\")\\\"; expected_sha=\\\"$(jq -er '.archive_sha256' \\\"$state\\\")\\\"; expected_size=\\\"$(jq -er '.archive_size_bytes' \\\"$state\\\")\\\"\"},{\"file\":\"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker\",\"line\":\"124: base=\\\"$(prepare_cloud_a_manifest \\\"$vmid\\\" \\\"$gen\\\" \\\"$state\\\" \\\"$work\\\")\\\"; manifest=\\\"$work/PARTS.tsv\\\"; fifo=\\\"$work/archive.sha.fifo\\\"; sha_out=\\\"$work/archive.sha256\\\"; mkfifo -m 0600 \\\"$fifo\\\"\"},{\"file\":\"/usr/local/libexec/homelab-app-cloud-quorum-worker\",\"line\":\"352: base=\\\"$(jq -er '.remote_a_base' \\\"$state\\\")\\\"; expected_msha=\\\"$(jq -er '.parts_manifest_sha256' \\\"$state\\\")\\\"\"},{\"file\":\"/usr/local/libexec/homelab-app-cloud-quorum-worker\",\"line\":\"353: manifest=\\\"$(dirname \\\"$out\\\")/PARTS.tsv\\\"; rclone cat \\\"${base%/}/PARTS.tsv\\\" >\\\"$manifest\\\"\"}]\nNO_MUTATION=true\nNO_BACKUP_STARTED=true\nNO_RESTORE_STARTED=true\nNO_RETENTION_STARTED=true\nNO_DELETE=true\nNO_MAIL_SENT=true\nTASK_RESULT=PASS_HOMELAB_BACKUP_CLOUDB_PREFLIGHT_RCA_READONLY\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SUPPORT-260921-HOMELAB-BACKUP-CLOUDB-PREFLIGHT-RCA-READONLY-1064R1\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\nWORKERS2_CLOUDB_RCA_END=1\n" + "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" } diff --git a/runtime/latest.txt b/runtime/latest.txt index 5fab162a..c6bbc532 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,15 +1,15 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=SUPPORT-260921-HOMELAB-BACKUP-CLOUDB-PREFLIGHT-RCA-READONLY-1064R1 +COMMAND_ID=SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2 STATUS=OK RC=0 HOST=pve01 MODE=read-only -COMPONENT=homelab-backup-cloudb-preflight-rca +COMPONENT=signalbot-semantic-conflict-identity-rca REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -COMMAND_SHA256=b508f92361099e24264836513bd255c236078b8a0b80039c6c69016e3bce2085 +COMMAND_SHA256=cdd4ca3200241b36187999fff08989c1a1e93b90c6e990ea45f78e300444f86f DUPLICATE_FAILED_COMMAND_BLOCKED=false EXECUTION_STARTED=true CHANGE_DECLARED=false @@ -24,32 +24,12 @@ MUTATION_OUTCOME=NO_MUTATION SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=a5e3e41807765a5f0bb7a13406d297e3deebf550a436821efe1df44356f9fa5c -SANITIZED_OUTPUT_SHA256=a5e3e41807765a5f0bb7a13406d297e3deebf550a436821efe1df44356f9fa5c +RAW_EVIDENCE_SHA256=96171914aa4f0df906f4a8d604c4ea16e0fe43b7634b08abc0b7596ab1f9940e +SANITIZED_OUTPUT_SHA256=96171914aa4f0df906f4a8d604c4ea16e0fe43b7634b08abc0b7596ab1f9940e OUTPUT_BEGIN -WORKERS2_CLOUDB_RCA_BEGIN=1 -COMMAND_ID=SUPPORT-260921-HOMELAB-BACKUP-CLOUDB-PREFLIGHT-RCA-READONLY-1064R1 -MODE=read-only -COMPONENT=homelab-backup-cloudb-preflight-rca -MUTATION_BOUNDARY=READ_ONLY_NO_REPO_WRITE_NO_SYSTEMD_ACTION_NO_BACKUP_NO_RESTORE_NO_RETENTION_NO_DELETE_NO_MAIL -STATE_INVENTORY={"latest_files":["app-skladchik-reports-monitor-pve01-20260921T033135Z.json","app-skladchik-reports-monitor-pve01-20260916T113630Z.json","app-skladchik-reports-monitor-pve01-20260915T223334Z.json","app-skladchik-reports-monitor-pve01-20260915T093500Z.json","app-skladchik-reports-monitor-pve01-20260914T193818Z.json","app-skladchik-reports-monitor-pve01-20260914T063210Z.json","app-skladchik-reports-monitor-pve01-20260913T174140Z.json","app-skladchik-reports-monitor-pve01-20260913T033047Z.json"],"sealed":57,"total":57} -LATEST_SEALED_STATE={"archive_sha256":"c41f0f9f871a6d16ae9ba98c2e40b06f9107082d6f9985dcb2e0a19c34412140","archive_size_bytes":178434,"cloud_a_verified":true,"cloud_b_verified":true,"cloud_quorum":2,"generation":"app-skladchik-reports-monitor-pve01-20260921T033135Z","local_cleanup":"OK","local_payload_present":false,"logical_id":"app-skladchik-reports-monitor","part_count":1,"part_hashes_verified":true,"parts_manifest_sha256":"94b2185cab444b7835946dc3fd009adc7103ac09f1f607e93b9b328dbfeccedf","payload_name":"app-skladchik-reports-monitor-pve01-20260921T033135Z.tar.zst","remote_a_base":"pve01-mail-01-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z","remote_b_base":"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z","schema":"homelab-cloud-quorum-payload-v1","seal_written":true,"state_file":"app-skladchik-reports-monitor-pve01-20260921T033135Z.json","state_sha256":"41c4e42953c36022ea4f18b5451ec70ea251c86542502444e748545ffa799271","status":"SEALED","types":{"archive_sha256":"str","archive_size_bytes":"int","cloud_a_verified":"bool","cloud_b_verified":"bool","cloud_quorum":"int","generation":"str","local_cleanup":"str","local_payload_present":"bool","logical_id":"str","part_count":"int","part_hashes_verified":"bool","parts_manifest_sha256":"str","payload_name":"str","remote_a_base":"str","remote_b_base":"str","schema":"str","seal_written":"bool","status":"str"}} -STATE_RELEVANT_KEYS=[{"path":"status","type":"str","value":"SEALED"},{"path":"generation","type":"str","value":"app-skladchik-reports-monitor-pve01-20260921T033135Z"},{"path":"payload_path","type":"str","value":"/mnt/staging/homelab-app-cloud-quorum/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z.tar.zst"},{"path":"payload_name","type":"str","value":"app-skladchik-reports-monitor-pve01-20260921T033135Z.tar.zst"},{"path":"archive_size_bytes","type":"int","value":178434},{"path":"archive_sha256","type":"str","value":"c41f0f9f871a6d16ae9ba98c2e40b06f9107082d6f9985dcb2e0a19c34412140"},{"path":"part_count","type":"int","value":1},{"path":"remote_a_root","type":"str","value":"pve01-mail-01-crypt:homelab-backups"},{"path":"remote_b_root","type":"str","value":"pve01-mail-02-crypt:homelab-backups"},{"path":"remote_a_base","type":"str","value":"pve01-mail-01-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z"},{"path":"remote_b_base","type":"str","value":"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z"},{"path":"cloud_a_verified","type":"bool","value":true},{"path":"cloud_b_verified","type":"bool","value":true},{"path":"cloud_a_reconstructed_sha256","type":"str","value":"c41f0f9f871a6d16ae9ba98c2e40b06f9107082d6f9985dcb2e0a19c34412140"},{"path":"cloud_b_reconstructed_sha256","type":"str","value":"c41f0f9f871a6d16ae9ba98c2e40b06f9107082d6f9985dcb2e0a19c34412140"},{"path":"cloud_a_verified_at_utc","type":"str","value":"2026-09-21T03:31:38Z"},{"path":"cloud_b_verified_at_utc","type":"str","value":"2026-09-21T03:31:43Z"},{"path":"cloud_quorum","type":"int","value":2},{"path":"part_hashes_verified","type":"bool","value":true},{"path":"parts_manifest_sha256","type":"str","value":"94b2185cab444b7835946dc3fd009adc7103ac09f1f607e93b9b328dbfeccedf"},{"path":"local_payload_present","type":"bool","value":false},{"path":"cloud_a_seal_verified","type":"bool","value":true},{"path":"cloud_b_seal_verified","type":"bool","value":true},{"path":"cloud_a_seal_verified_at_utc","type":"str","value":"2026-09-21T03:31:48Z"},{"path":"cloud_b_seal_verified_at_utc","type":"str","value":"2026-09-21T03:31:48Z"}] -CLOUDB_STRING_CANDIDATES=[{"path":"remote_b_root","value":"pve01-mail-02-crypt:homelab-backups"},{"path":"remote_b_base","value":"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z"}] -RESTORE_EVIDENCE={"exists":true,"file":"app-skladchik-reports-monitor-pve01-20260921T033135Z.json","restore_source":"Cloud A","result":"OK"} -CLOUDB_REMOTE_CHECKS=[{"base":"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z","lsf_rc":0,"manifest_candidates":[{"bytes":99,"matches_state_count":true,"matches_state_manifest_sha":true,"matches_state_size":true,"path":"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z/PARTS.tsv","rc":0,"rows":1,"sha256":"94b2185cab444b7835946dc3fd009adc7103ac09f1f607e93b9b328dbfeccedf","total_size":178434},{"bytes":0,"path":"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z.parts/PARTS.tsv","rc":3},{"bytes":0,"path":"pve01-mail-02-crypt:homelab-backups/app-skladchik-reports-monitor/app-skladchik-reports-monitor-pve01-20260921T033135Z/parts/PARTS.tsv","rc":3}],"source":"remote_b_base","top_names":["PARTS.tsv","payload.parts/","seal.json"]},{"base":"pve01-mail-02-crypt:homelab-backups","lsf_rc":0,"manifest_candidates":[{"bytes":0,"path":"pve01-mail-02-crypt:homelab-backups/PARTS.tsv","rc":3},{"bytes":0,"path":"pve01-mail-02-crypt:homelab-backups.parts/PARTS.tsv","rc":3},{"bytes":0,"path":"pve01-mail-02-crypt:homelab-backups/parts/PARTS.tsv","rc":3}],"source":"remote_b_root","top_names":["app-filebrowser/","app-hbarhub/","app-immich/","app-memos/","app-scrutiny/","app-skladchik-moderator-assistant/","app-skladchik-reports-monitor/","control-bootstrap/","control-bootstrap-v2/","hb/","pve01/","retention-canary/","vm110/","vm111/","vm112/","vm113/","vm130/","vm150/","vm160/","vm170/","vm171/","vm180/","vm190/","vm200/","vm211/","vm9130/"]}] -RCA_CLASSIFICATION={"fix":"REUSE_PROVEN_STATE_AND_MANIFEST_LAYOUT_WITH_CORRECTED_PREFLIGHT","root_cause":"CLOUDB_PREFLIGHT_IMPLEMENTATION_BUG"} -TRANSPORT_SOURCE_FILES=["/usr/local/sbin/homelab-rotating-boot-drill-state-export","/usr/local/sbin/homelab-control-backup","/usr/local/sbin/homelab-rotating-boot-drill","/usr/local/libexec/homelab-rotating-boot-drill-state-export","/usr/local/libexec/homelab-cloud-quorum-payload","/usr/local/libexec/homelab-vm-cloud-quorum-node-worker","/usr/local/libexec/homelab-app-cloud-quorum-worker"] -TRANSPORT_SOURCE_HITS=[{"file":"/usr/local/sbin/homelab-rotating-boot-drill-state-export","line":"31: if not isinstance(obj.get(\"archive_size_bytes\"),int) or obj[\"archive_size_bytes\"] <= 0: return False"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill-state-export","line":"32: if not isinstance(obj.get(\"part_count\"),int) or obj[\"part_count\"] <= 0: return False"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill-state-export","line":"34: if not isinstance(obj.get(\"parts_manifest_sha256\"),str) or not HEX64.fullmatch(obj[\"parts_manifest_sha256\"]): return False"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill-state-export","line":"42: if obj.get(\"remote_a_base\") != expect_a or obj.get(\"remote_b_base\") != expect_b: return False"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill-state-export","line":"84: \"archive_size_bytes\":obj[\"archive_size_bytes\"],"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill-state-export","line":"86: \"parts_manifest_sha256\":obj[\"parts_manifest_sha256\"],"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill-state-export","line":"87: \"part_count\":obj[\"part_count\"],"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill-state-export","line":"89: \"remote_b_base\":obj[\"remote_b_base\"],"},{"file":"/usr/local/sbin/homelab-control-backup","line":"72: expected_manifest=\"$(jq -er '.parts_manifest_sha256' \"$state\")\"; expected_archive=\"$(jq -er '.archive_sha256' \"$state\")\""},{"file":"/usr/local/sbin/homelab-control-backup","line":"73: manifest=\"${out}.PARTS.tsv\"; : >\"$out\""},{"file":"/usr/local/sbin/homelab-control-backup","line":"74: rclone --config \"$cfg\" cat \"${base%/}/PARTS.tsv\" >\"$manifest\" || die \"REMOTE_${label}_MANIFEST_READ_FAILED\" 74"},{"file":"/usr/local/sbin/homelab-control-backup","line":"96: base_a=\"$(jq -er '.remote_a_base' \"$state\")\"; base_b=\"$(jq -er '.remote_b_base' \"$state\")\"; a=\"$work/A.tar.gz\"; b=\"$work/B.tar.gz\""},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"374: base=info[\"remote_a_base\"] if cloud==\"A\" else info[\"remote_b_base\"]"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"376: manifest_bytes=rclone_cat(base.rstrip(\"/\")+\"/PARTS.tsv\",60)"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"382: \"archive_size_bytes\":info[\"archive_size_bytes\"],\"archive_sha256\":info[\"archive_sha256\"],"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"383: \"part_count\":info[\"part_count\"],\"parts_manifest_sha256\":info[\"parts_manifest_sha256\"],"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"388: if hashlib.sha256(manifest_bytes).hexdigest()!=info[\"parts_manifest_sha256\"]: die(\"REMOTE_MANIFEST_SHA_MISMATCH_\"+info[\"vmid\"],66)"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"389: rows=parse_manifest(manifest_bytes,info[\"part_count\"],info[\"archive_size_bytes\"])"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"420: need_stage=qinfo[\"archive_size_bytes\"]+linfo[\"archive_size_bytes\"]+p[\"minimum_stage_headroom_bytes\"]"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"438: \"qemu_archive_bytes\":qi[\"archive_size_bytes\"],\"lxc_archive_bytes\":li[\"archive_size_bytes\"],"},{"file":"/usr/local/sbin/homelab-rotating-boot-drill","line":"583: if total!=info[\"archive_size_bytes\"] or h.hexdigest()!=info[\"archive_sha256\"]: die(\"ARCHIVE_VERIFY_FAILED_\"+info[\"vmid\"],70)"},{"file":"/usr/local/libexec/homelab-rotating-boot-drill-state-export","line":"31: if not isinstance(obj.get(\"archive_size_bytes\"),int) or obj[\"archive_size_bytes\"] <= 0: return False"},{"file":"/usr/local/libexec/homelab-rotating-boot-drill-state-export","line":"32: if not isinstance(obj.get(\"part_count\"),int) or obj[\"part_count\"] <= 0: return False"},{"file":"/usr/local/libexec/homelab-rotating-boot-drill-state-export","line":"34: if not isinstance(obj.get(\"parts_manifest_sha256\"),str) or not HEX64.fullmatch(obj[\"parts_manifest_sha256\"]): return False"},{"file":"/usr/local/libexec/homelab-rotating-boot-drill-state-export","line":"42: if obj.get(\"remote_a_base\") != expect_a or obj.get(\"remote_b_base\") != expect_b: return False"},{"file":"/usr/local/libexec/homelab-rotating-boot-drill-state-export","line":"84: \"archive_size_bytes\":obj[\"archive_size_bytes\"],"},{"file":"/usr/local/libexec/homelab-rotating-boot-drill-state-export","line":"86: \"parts_manifest_sha256\":obj[\"parts_manifest_sha256\"],"},{"file":"/usr/local/libexec/homelab-rotating-boot-drill-state-export","line":"87: \"part_count\":obj[\"part_count\"],"},{"file":"/usr/local/libexec/homelab-rotating-boot-drill-state-export","line":"89: \"remote_b_base\":obj[\"remote_b_base\"],"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"198: --arg remote_b_base \"$REMOTE_B_BASE\" \\"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"201: --argjson part_count \"$PART_COUNT\" \\"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"205: archive_size_bytes:$payload_size,archive_sha256:$payload_sha,"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"206: chunk_size_bytes:$chunk_size,part_count:$part_count,"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"208: remote_a_base:$remote_a_base,remote_b_base:$remote_b_base,"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"212: cloud_quorum:0,part_hashes_verified:false,parts_manifest_sha256:null,"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"230: --arg remote_b_base \"$REMOTE_B_BASE\" \\"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"232: --argjson part_count \"$PART_COUNT\" \\"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"235: .archive_size_bytes==$payload_size and"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"237: .part_count==$part_count and"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"239: .remote_b_base==$remote_b_base' \\"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"248: PAYLOAD_SIZE=\"$(jq -er '.archive_size_bytes | numbers | select(.>0 and floor==.)' \"$STATE_FILE\")\" || die \"STATE_PAYLOAD_SIZE_INVALID\" 65"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"249: PART_COUNT=\"$(jq -er '.part_count | numbers | select(.>0 and floor==.)' \"$STATE_FILE\")\" || die \"STATE_PART_COUNT_INVALID\" 65"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"452: .parts_manifest_sha256=$manifest_sha' \\"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"463: saved_manifest=\"$(jq -er '.parts_manifest_sha256 | strings | select(test(\"^[0-9a-f]{64}$\"))' \"$STATE_FILE\")\" || die \"STATE_PARTS_MANIFEST_SHA_INVALID\" 65"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"535: .parts_manifest_sha256==null"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"540: (.parts_manifest_sha256 |"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"560:PARTS_MANIFEST=\"$WORK/PARTS.tsv\""},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"636: printf '%s\\n' \"${base%/}/PARTS.tsv\""},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"687: PARTS_MANIFEST_SHA=\"$(jq -er '.parts_manifest_sha256 | strings | select(test(\"^[0-9a-f]{64}$\"))' \"$STATE_FILE\")\" || die \"STATE_PARTS_MANIFEST_SHA_INVALID\" 65"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"700: remote_manifest=\"$WORK/remote-${label}-PARTS.tsv\""},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"836: archive_size_bytes:.archive_size_bytes,"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"839: part_count:.part_count,"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"840: parts_manifest_sha256:.parts_manifest_sha256,"},{"file":"/usr/local/libexec/homelab-cloud-quorum-payload","line":"856: (.parts_manifest_sha256|type==\"string\" and test(\"^[0-9a-f]{64}$\")) and"},{"file":"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker","line":"89: base=\"$(jq -er '.remote_a_base' \"$state\")\"; expected_msha=\"$(jq -er '.parts_manifest_sha256' \"$state\")\"; expected_count=\"$(jq -er '.part_count' \"$state\")\"; expected_size=\"$(jq -er '.archive_size_bytes' \"$state\")\""},{"file":"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker","line":"91: manifest=\"$work/PARTS.tsv\"; rclone cat \"${base%/}/PARTS.tsv\" >\"$manifest\""},{"file":"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker","line":"121: payload_name=\"$(jq -er '.payload_name' \"$state\")\"; expected_sha=\"$(jq -er '.archive_sha256' \"$state\")\"; expected_size=\"$(jq -er '.archive_size_bytes' \"$state\")\""},{"file":"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker","line":"124: base=\"$(prepare_cloud_a_manifest \"$vmid\" \"$gen\" \"$state\" \"$work\")\"; manifest=\"$work/PARTS.tsv\"; fifo=\"$work/archive.sha.fifo\"; sha_out=\"$work/archive.sha256\"; mkfifo -m 0600 \"$fifo\""},{"file":"/usr/local/libexec/homelab-app-cloud-quorum-worker","line":"352: base=\"$(jq -er '.remote_a_base' \"$state\")\"; expected_msha=\"$(jq -er '.parts_manifest_sha256' \"$state\")\""},{"file":"/usr/local/libexec/homelab-app-cloud-quorum-worker","line":"353: manifest=\"$(dirname \"$out\")/PARTS.tsv\"; rclone cat \"${base%/}/PARTS.tsv\" >\"$manifest\""}] -NO_MUTATION=true -NO_BACKUP_STARTED=true -NO_RESTORE_STARTED=true -NO_RETENTION_STARTED=true -NO_DELETE=true -NO_MAIL_SENT=true -TASK_RESULT=PASS_HOMELAB_BACKUP_CLOUDB_PREFLIGHT_RCA_READONLY -HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260921-HOMELAB-BACKUP-CLOUDB-PREFLIGHT-RCA-READONLY-1064R1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} -WORKERS2_CLOUDB_RCA_END=1 +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"}} +TASK_RESULT=PASS_SIGNALBOT_052SEM2_CONFLICT_IDENTITIES_CAPTURED +HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SIGNALBOT-260921-SEMANTIC-CONFLICT-IDENTITY-RCA-052SEM2","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} OUTPUT_END CHAT_OUTPUT_END