1
0

runtime: publish SIGNALBOT-260921-RECONCILIATION-FETCH-CALLSITE-READONLY-052SRC2

This commit is contained in:
homelab-runtime-publisher
2026-09-21 03:17:14 +00:00
parent 4b78f8af7f
commit c6ea068925
4 changed files with 138 additions and 153 deletions
@@ -0,0 +1,38 @@
{
"schema_version": 1,
"channel": "homelab-runtime",
"command_id": "SIGNALBOT-260921-RECONCILIATION-FETCH-CALLSITE-READONLY-052SRC2",
"status": "OK",
"rc": 0,
"host": "pve01",
"mode": "read-only",
"component": "signalbot-reconciliation-fetch-callsite-readonly",
"started_at_utc": "2026-09-21T03:17:13Z",
"finished_at_utc": "2026-09-21T03:17:14Z",
"reference_register_checked": true,
"reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66",
"error_register_checked": true,
"error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0",
"command_sha256": "a2394e2215fc751b3d1ff578290cdb8a4ff61a0f8db3d9fe99fe41d928009871",
"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": "bf196e2a68fb862baf3f45a031942ecc28847aa8c27da807cc17d4a3d36f7894",
"sanitized_output_sha256": "bf196e2a68fb862baf3f45a031942ecc28847aa8c27da807cc17d4a3d36f7894",
"output_truncated_in_json": false,
"full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt",
"output": "SIGNALBOT052SRC2_RESULT={\"evidence\":\"023ce0a041b50b866a48d9f752bd80479a34789d82f73c81d18246ed8871ef8e /app/demonov_forward_map/bitfinex_reconciliation.py\\nclass BitfinexPublicTradeHistoryClient:\\n def __init__(\\n self,\\n *,\\n fetch_json: Callable[..., object] | None = None,\\n timeout: float = 20.0,\\n max_bytes: int = 4 * 1024 * 1024,\\n ) -> None:\\n self._fetch_json = fetch_json or _stdlib_fetch_json\\n self.timeout = float(timeout)\\n self.max_bytes = int(max_bytes)\\n\\n 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 raise DemonovError(\\\"Bitfinex public trade history not ascending\\\")\\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\",\"guest_exitcode\":0,\"outer_rc\":0,\"stderr_present\":false}\nTASK_RESULT=PASS_SIGNALBOT_052SRC2_CALLSITE_CAPTURED\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SIGNALBOT-260921-RECONCILIATION-FETCH-CALLSITE-READONLY-052SRC2\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n"
}
@@ -0,0 +1,35 @@
CHAT_OUTPUT_BEGIN
COMMAND_ID=SIGNALBOT-260921-RECONCILIATION-FETCH-CALLSITE-READONLY-052SRC2
STATUS=OK
RC=0
HOST=pve01
MODE=read-only
COMPONENT=signalbot-reconciliation-fetch-callsite-readonly
REFERENCE_REGISTER_CHECK=OK
REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66
ERROR_REGISTER_CHECK=OK
ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0
COMMAND_SHA256=a2394e2215fc751b3d1ff578290cdb8a4ff61a0f8db3d9fe99fe41d928009871
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=bf196e2a68fb862baf3f45a031942ecc28847aa8c27da807cc17d4a3d36f7894
SANITIZED_OUTPUT_SHA256=bf196e2a68fb862baf3f45a031942ecc28847aa8c27da807cc17d4a3d36f7894
OUTPUT_BEGIN
SIGNALBOT052SRC2_RESULT={"evidence":"023ce0a041b50b866a48d9f752bd80479a34789d82f73c81d18246ed8871ef8e /app/demonov_forward_map/bitfinex_reconciliation.py\nclass BitfinexPublicTradeHistoryClient:\n def __init__(\n self,\n *,\n fetch_json: Callable[..., object] | None = None,\n timeout: float = 20.0,\n max_bytes: int = 4 * 1024 * 1024,\n ) -> None:\n self._fetch_json = fetch_json or _stdlib_fetch_json\n self.timeout = float(timeout)\n self.max_bytes = int(max_bytes)\n\n 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 raise DemonovError(\"Bitfinex public trade history not ascending\")\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","guest_exitcode":0,"outer_rc":0,"stderr_present":false}
TASK_RESULT=PASS_SIGNALBOT_052SRC2_CALLSITE_CAPTURED
HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SIGNALBOT-260921-RECONCILIATION-FETCH-CALLSITE-READONLY-052SRC2","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null}
OUTPUT_END
CHAT_OUTPUT_END
+38 -1
View File
@@ -1 +1,38 @@
{"schema_version":1,"channel":"homelab-runtime","command_id":"CONTEXT-AUTO-20260921T031701Z","status":"OK","rc":0,"host":"pve01","mode":"read-only","component":"cluster-context","started_at_utc":"2026-09-21T03:17:01Z","finished_at_utc":"2026-09-21T03:17:02Z","reference_register_checked":true,"reference_sha256":"5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66","error_register_checked":true,"error_register_sha256":"3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0","changes_made":false,"sanitized":true,"secrets_included":false,"private_addresses_included":false,"output":"AUTOMATIC_CLUSTER_CONTEXT_REFRESH=OK"}
{
"schema_version": 1,
"channel": "homelab-runtime",
"command_id": "SIGNALBOT-260921-RECONCILIATION-FETCH-CALLSITE-READONLY-052SRC2",
"status": "OK",
"rc": 0,
"host": "pve01",
"mode": "read-only",
"component": "signalbot-reconciliation-fetch-callsite-readonly",
"started_at_utc": "2026-09-21T03:17:13Z",
"finished_at_utc": "2026-09-21T03:17:14Z",
"reference_register_checked": true,
"reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66",
"error_register_checked": true,
"error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0",
"command_sha256": "a2394e2215fc751b3d1ff578290cdb8a4ff61a0f8db3d9fe99fe41d928009871",
"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": "bf196e2a68fb862baf3f45a031942ecc28847aa8c27da807cc17d4a3d36f7894",
"sanitized_output_sha256": "bf196e2a68fb862baf3f45a031942ecc28847aa8c27da807cc17d4a3d36f7894",
"output_truncated_in_json": false,
"full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt",
"output": "SIGNALBOT052SRC2_RESULT={\"evidence\":\"023ce0a041b50b866a48d9f752bd80479a34789d82f73c81d18246ed8871ef8e /app/demonov_forward_map/bitfinex_reconciliation.py\\nclass BitfinexPublicTradeHistoryClient:\\n def __init__(\\n self,\\n *,\\n fetch_json: Callable[..., object] | None = None,\\n timeout: float = 20.0,\\n max_bytes: int = 4 * 1024 * 1024,\\n ) -> None:\\n self._fetch_json = fetch_json or _stdlib_fetch_json\\n self.timeout = float(timeout)\\n self.max_bytes = int(max_bytes)\\n\\n 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 raise DemonovError(\\\"Bitfinex public trade history not ascending\\\")\\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\",\"guest_exitcode\":0,\"outer_rc\":0,\"stderr_present\":false}\nTASK_RESULT=PASS_SIGNALBOT_052SRC2_CALLSITE_CAPTURED\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SIGNALBOT-260921-RECONCILIATION-FETCH-CALLSITE-READONLY-052SRC2\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n"
}
+27 -152
View File
File diff suppressed because one or more lines are too long