Spaces:
Paused
Paused
File size: 65,896 Bytes
848e6c4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 | # Hermes Futures Desk — Complete Developer Documentation
> Canonical combined developer reference for the UI v3 repository snapshot. The modular source documents live under `asset-space/docs/`.
## Contents
1. [Developer Guide](#developer-guide)
2. [Architecture](#architecture)
3. [API Reference](#api-reference)
4. [Datasource Pipeline and Contracts](#datasource-pipeline-and-contracts)
5. [Frontend Guide](#frontend-guide)
6. [Environment Configuration](#environment-configuration)
7. [Deployment Runbook](#deployment-runbook)
8. [Security and Safety](#security-and-safety)
9. [Operations and Troubleshooting](#operations-and-troubleshooting)
10. [Testing and Verification](#testing-and-verification)
11. [Contributing](#contributing)
12. [Project Status](#project-status)
---
## Hermes Futures Desk — Complete Developer Guide
### 1. Purpose
Hermes Futures Desk is an authenticated Futures analysis and risk-management layer installed into the existing Hermes Agent runtime. It discovers markets, normalizes real market data, produces deterministic `LONG`, `SHORT`, or `NO_TRADE` outcomes, calculates a bounded trade plan, applies server-side risk controls, and optionally routes a fully revalidated plan to the existing Paper execution path.
The system is intentionally conservative:
- Datasource 4 is authoritative for Futures verification and safety.
- Binance public data may fill missing or unusable market fields but cannot override DS4 safety.
- Datasource 2 provides complementary context only.
- External AI provides advisory explanation only.
- The browser is never trusted to authorize execution.
- No new web server, FastAPI application, port, or trading engine is created.
### 2. Runtime summary
```text
Hugging Face Space / Docker container
└── /opt/hermes Upstream Hermes Agent source/runtime
├── dashboard on 0.0.0.0:7860 Existing Hermes web application
├── tools/futures_dashboard_api.py Installed repository overlay
├── tools/templates/...html Installed Luxury dashboard template
├── trading/* Installed Futures modules
└── .hermes_futures_overlay_manifest.json
/opt/data
├── scripts/ Entrypoint, persistence, runtime audit
├── hermes_overlay/ Restored/persisted copy; not preferred over image overlay
├── futures_symbols_cache.json Optional symbol cache
├── telegram_state.json Telegram owner/watchlist/alert state
└── persistent Hermes data
/opt/hermesface_overlay Immutable overlay copied from the current image
```
The Docker image clones Hermes Agent into `/opt/hermes`, installs Python/Node dependencies, copies repository scripts into `/opt/data/scripts`, and copies the current overlay into both `/opt/data/hermes_overlay` and `/opt/hermesface_overlay`. At startup, `scripts/sync_hf.py` installs the overlay into `/opt/hermes`, writes a SHA-256 manifest, patches the existing Hermes dashboard to include the routers, and starts the dashboard on port `7860`.
### 3. Main modules
| Module | Responsibility |
|---|---|
| `scripts/entrypoint.sh` | Runtime directory creation, dashboard auth configuration, and handoff to `sync_hf.py`. |
| `scripts/sync_hf.py` | Persistence restore/sync, overlay installation, manifest generation, router mounting, Telegram polling isolation, and process startup. |
| `hermes_overlay/tools/futures_dashboard_api.py` | Authenticated Futures HTTP routes, runtime file diagnostics, symbol catalog, market endpoint, analysis route, and Paper revalidation route. |
| `hermes_overlay/tools/templates/hermes_futures_desk_luxury.html` | Luxury Obsidian & Gold single-page dashboard. |
| `hermes_overlay/trading/dual_datasource_client.py` | DS4 → Binance → DS2 acquisition, normalization, provenance, health metadata, and `noTradeGuard` aggregation. |
| `hermes_overlay/trading/binance_public_client.py` | Unauthenticated Binance Futures fallback and explicit regional-restriction reporting. |
| `hermes_overlay/trading/trade_cycle.py` | Deterministic signal scoring, SL/TP construction, risk sizing, plan creation, and optional Paper orchestration. |
| `hermes_overlay/trading/risk.py` | Risk profiles, leverage caps/haircut, quantity sizing, and hard risk gates. |
| `hermes_overlay/trading/futures_execution.py` | Existing Paper account/position book and execution validation. |
| `hermes_overlay/trading/state.py` | Bounded in-memory dashboard state; no decision authority. |
| `hermes_overlay/trading/symbols.py` | Symbol normalization for DS4 and CCXT formats. |
| `hermes_overlay/external_ai/advisory.py` | Optional OpenRouter → Google → Hugging Face advisory chain. |
| `hermes_overlay/tools/telegram_bot.py` | Webhook-only, analysis-only Telegram adapter and owner bootstrap. |
| `scripts/verify_futures_runtime.py` | Read-only deployed runtime audit; never calls Paper Execute. |
### 4. End-to-end request flow
#### 4.1 Market display
1. Browser requests `GET /api/futures/market` with symbol, interval, and limit.
2. Router normalizes the symbol and calls `get_market_context()`.
3. Datasource client requests DS4 with bounded KuCoin-compatible millisecond `from`/`to` parameters.
4. Missing, unusable, or stale fields are requested from Binance public fallback.
5. Datasource 2 is queried for complementary context and may fill only still-missing legitimate fields.
6. Each normalized field receives source, timestamp, freshness, validity, and fallback metadata.
7. The endpoint returns only real normalized values or an explicit `partial`, `stale`, or `unavailable` state.
8. The browser renders charts and diagnostics without modifying server decisions.
#### 4.2 Deterministic analysis
1. Browser sends `POST /api/futures/analyze`.
2. Server runs `run_futures_cycle(..., execute=False)`.
3. DS4 safety state, Futures verification, required fields, and freshness gates are checked first.
4. A deterministic score is calculated only from normalized real inputs.
5. A directional plan is created only when score and confirmation thresholds pass.
6. SL/TP are derived from ATR and configured reward-to-risk rules.
7. Risk sizing calculates quantity from equity loss at Stop Loss.
8. Slippage is estimated from the real order book.
9. The result is stored as a bounded server-side plan and returned with a `planId`.
#### 4.3 Paper execution
Paper execution is not a continuation of browser state. The server performs all checks again:
- requested symbol is a verified Futures contract;
- `planId` matches the latest server plan;
- symbol and risk profile have not changed;
- plan was not already executed;
- plan has not expired;
- decision is `LONG` or `SHORT`;
- DS4 verification and trading readiness remain valid;
- `noTradeGuard` is false;
- plan is marked executable and risk-approved;
- runtime trading mode is `paper`;
- a fresh analysis-only cycle still authorizes the plan.
Only after these checks does the server invoke the existing Paper execution path.
### 5. Datasource authority
```text
Datasource 4 → Binance public fallback → Datasource 2
```
Datasource 4 owns contract verification and all Futures safety semantics. The critical fields are:
```text
contract
ticker
orderbook
funding
openInterest
```
OHLCV, indicators, sentiment, and ATR are also normalized and attributed. Missing or non-fresh critical fields activate `noTradeGuard` and set `tradingReadiness=blocked`.
Binance public data is unauthenticated and field-level only. HTTP 451 is represented as `Regionally restricted`; it is never reported as healthy. Datasource 2 cannot verify Futures, clear `noTradeGuard`, or override DS4 data that is present and usable.
### 6. Health model
The code deliberately separates:
- `transportStatus`: whether the HTTP request succeeded;
- `dataUsability`: whether parsed data is suitable for use;
- `freshness`: whether provider timestamp or authoritative DS4 state proves freshness;
- `completeness`: whether expected fields were supplied;
- `mergeStatus`: whether the combined context is complete;
- `tradingReadiness`: whether deterministic safety gates allow a plan.
A successful HTTP response does not make market data fresh. Fallback data without a provider timestamp remains `unknown` and cannot pass a Futures freshness gate.
### 7. Analysis and plan states
#### Analysis states
```text
NOT_ANALYZED
ANALYZING
LONG
SHORT
NO_TRADE
ANALYSIS_FAILED
STALE
API_UNAVAILABLE
```
#### Plan types
- `directional_plan`: a valid directional plan before final execution checks.
- `non_executable_plan`: directional values exist but one or more safety/risk gates block execution.
- rejected/no-direction analysis: `NO_TRADE` with no executable plan geometry.
#### Market endpoint states
- `available`: real candles and required display fields are fresh and usable.
- `partial`: values exist but freshness or completeness is not fully proven.
- `stale`: required display data is stale or invalid.
- `unavailable`: real candles or a current price could not be obtained.
### 8. Deterministic scoring and risk rules
Default analysis thresholds are environment-overridable:
| Setting | Default |
|---|---:|
| Minimum absolute signal score | `0.55` |
| Minimum signal components | `3` |
| Minimum direction confirmations | `2` |
| Stop ATR multiplier | `1.2` |
| Take Profit reward-to-risk | `1.8` |
| Minimum stop distance | `20` bps |
| Plan maximum age | `20` seconds |
| Requested leverage | `5x` |
Risk profiles:
| Profile | Equity risk | Maximum leverage |
|---|---:|---:|
| Conservative | 1% | 5x |
| Moderate | 3% | 10x |
| Aggressive | 5% | 15x |
Sizing is based on loss at Stop Loss:
```text
risk_amount = account_equity × risk_percent
stop_distance = abs(entry_price - stop_loss)
quantity = risk_amount / stop_distance
```
When ATR is at least 3% of price, effective leverage is reduced by 50% and never increased beyond the risk-profile cap.
### 9. Frontend behavior
The dashboard is a single packaged HTML template with inline CSS and JavaScript. It uses the existing authenticated FastAPI origin and `fetch(..., credentials='same-origin', cache='no-store')`.
Major features:
- symbol search and verified/market-only catalog counts;
- local watchlist and recent markets;
- real candle/line chart, four intervals, three candle limits, volume, crosshair, and tooltip;
- market source, freshness, funding, Open Interest, best bid/ask/spread, and readiness;
- display-only diagnostics from returned candles;
- per-field provenance;
- deterministic analysis and Paper Execute controls;
- plan geometry and execution checklist;
- datasource detail cards and sanitized technical diagnostics;
- Paper account and positions;
- local activity/history, JSON export, copy summary, density/theme preferences;
- manual and automatic refresh controls.
Browser storage never grants server permission. Selecting a historical symbol or changing risk invalidates the current browser plan and requires a new server analysis.
### 10. Authentication
The upstream Hermes dashboard is protected by its existing authentication middleware. The Futures router also supports local HTTP Basic enforcement when `HERMES_ADMIN_PASSWORD` is set:
```text
username: HERMES_DASHBOARD_BASIC_AUTH_USERNAME (default: admin)
password: HERMES_ADMIN_PASSWORD
```
`entrypoint.sh` writes a hashed credential into Hermes `config.yaml` before the server binds publicly. Secrets must be configured as Hugging Face Space secrets or injected environment variables, never committed.
### 11. Telegram model
Telegram is webhook-only and analysis-only:
- `POST /api/telegram/webhook` validates `X-Telegram-Bot-Api-Secret-Token`.
- Owner bootstrap uses a one-time private-chat `/claim <secret>` command.
- Authorized users come from configured IDs or the persisted owner.
- Commands call `run_futures_cycle(..., execute=False)` only.
- Direct delivery may use a proxy; proactive delivery may use an HMAC relay.
- Polling must remain disabled.
No Telegram command can execute a Futures position.
### 12. Runtime integrity
During overlay installation, `sync_hf.py` copies the current image overlay into `/opt/hermes` and writes `.hermes_futures_overlay_manifest.json`. The status endpoint compares repository/overlay/runtime/template/router hashes when those paths are available.
Runtime status semantics:
- `verified`: evidence exists and all expected hashes match;
- `mismatch`: evidence exists and one or more hashes differ;
- `unknown`: required evidence is unavailable.
Missing files must never be reported as verified.
### 13. Development workflow
1. Start from the current repository files under `asset-space/hermes_overlay`.
2. Do not copy old loose reference files over the repository.
3. Keep changes focused and additive to the API contract.
4. Preserve the single server and port architecture.
5. Add tests for normalization, provenance, state transitions, and server-side execution checks.
6. Run static checks and focused Futures tests.
7. Review secrets and generated files before commit.
8. Deploy through the existing Space workflow.
9. Verify the installed hashes and authenticated routes.
10. Inspect browser Console and Network.
11. Never click Paper Execute during deployment verification.
### 14. Read-only runtime audit
```bash
export HERMES_ADMIN_PASSWORD='...'
export HERMES_DASHBOARD_BASIC_AUTH_USERNAME='admin'
python scripts/verify_futures_runtime.py \
--base-url https://really-amin-asset.hf.space \
--symbol BTCUSDT \
--analyze \
--report .runtime_audit/futures_runtime_audit.json
```
The utility checks `/futures`, status, symbols, positions, all market intervals, and optionally one analysis-only request. It never calls `/api/futures/paper/execute`.
### 15. Known deployment limitations
- Binance public Futures endpoints may return HTTP 451 in the current Hugging Face region.
- Real DS4 payload names and provider timestamps must be verified against live deployed responses.
- The current package has static validation results but not a completed authenticated production verification cycle.
- The UI uses a single large HTML template; future refactoring must preserve runtime template installation and avoid introducing a second frontend server.
### 16. Definition of done
A change is complete only when:
- the correct template and router are installed and hash-verified;
- authenticated routes return expected structured responses;
- real market data renders for 1m, 5m, 15m, and 1h or returns an explicit unavailable state;
- Console has no critical error and Network requests are authenticated;
- datasource health and attribution are truthful;
- deterministic safety logic is unchanged;
- Telegram remains webhook-only;
- no secret is exposed;
- no trade is executed during verification.
---
## Architecture
### System context
```mermaid
flowchart LR
U[Authenticated browser] -->|same-origin HTTPS| H[Hermes dashboard / FastAPI :7860]
T[Telegram webhook] --> H
H --> R[Futures dashboard router]
R --> C[Deterministic trade cycle]
R --> S[Dashboard state]
C --> D[Dual datasource client]
D --> DS4[Datasource 4\nAuthoritative]
D --> B[Binance public\nFallback]
D --> DS2[Datasource 2\nComplementary]
C --> K[Risk / sizing]
C --> E[Paper execution]
C -. advisory only .-> A[External AI]
```
### Container and filesystem architecture
```mermaid
flowchart TD
I[Docker image] --> O1[/opt/hermesface_overlay\nimmutable current-image overlay]
I --> O2[/opt/data/hermes_overlay\npersisted/restored copy]
I --> S[/opt/data/scripts]
B[scripts/entrypoint.sh] --> Y[scripts/sync_hf.py]
Y -->|prefer| O1
Y -->|fallback only| O2
Y -->|copy modules| H[/opt/hermes]
Y --> M[overlay manifest]
Y --> P[patch existing dashboard router]
P --> W[Hermes dashboard :7860]
```
The immutable `/opt/hermesface_overlay` is preferred so a restored dataset containing an older overlay cannot downgrade the current image.
### Layer responsibilities
#### HTTP and UI layer
`futures_dashboard_api.py` owns request validation, authentication dependency, response shaping, runtime diagnostics, and browser-facing error semantics. It does not implement signal scoring or sizing.
#### Datasource layer
`dual_datasource_client.py` owns:
- HTTP acquisition;
- KuCoin-compatible time range construction;
- nested payload discovery;
- field normalization;
- source priority;
- field provenance;
- source health metadata;
- `noTradeGuard`, missing-field, stale-field, merge, and readiness results.
#### Decision layer
`trade_cycle.py` owns deterministic score calculation, decision thresholds, SL/TP construction, risk module orchestration, plan expiry, and optional execution handoff.
#### Risk layer
`risk.py` owns risk profile lookup, leverage caps, volatility haircut, quantity calculation, margin/notional gates, daily-loss and position-count gates.
#### Execution layer
`futures_execution.py` owns Paper mode, account/position state, exchange adapter boundaries, slippage estimation, and protective order behavior. The dashboard route never directly constructs an exchange order.
#### State layer
`state.py` stores only a bounded view of the latest context/plan for the dashboard. It removes raw exchange payloads and does not authorize any decision.
### Trust boundaries
| Boundary | Trusted for decisions? | Notes |
|---|---|---|
| Browser controls and localStorage | No | Convenience only; server revalidates everything. |
| Datasource 4 | Yes, for verification/safety | Still subject to parsing, freshness, and completeness checks. |
| Binance public | No, as authority | Field fallback only; cannot clear DS4 guard. |
| Datasource 2 | No, as authority | Complementary context only. |
| External AI | No | Advisory explanation only. |
| Telegram input | No | Authorized, rate-limited, analysis-only commands. |
| Server-side latest plan | Partially | Must still pass freshness and execution revalidation. |
### Router installation
`sync_hf.py` modifies the existing Hermes dashboard code to include:
```python
from tools.futures_dashboard_api import router as _futures_dashboard_router
app.include_router(_futures_dashboard_router)
from tools.telegram_bot import router as _telegram_router
app.include_router(_telegram_router)
```
The patch is idempotent and must not create a new FastAPI app.
### Persistence
Hermes data under `/opt/data` may be synchronized to a private Hugging Face Dataset. The repository overlay is also copied into the image, but the immutable image overlay is the source used for installation. Runtime state such as Telegram owner data and symbol cache lives under `/opt/data` and must not be committed.
### Failure behavior
- DS4 unreachable: merge may use fallback data for display, but Futures verification/readiness remains blocked.
- Binance HTTP 451: source status is restricted/unavailable; no bypass is attempted.
- DS2 unavailable: complementary context is degraded; it does not independently block a plan unless it was the only attempted fill for a still-missing field.
- Market endpoint exception: HTTP 503 with structured `API_UNAVAILABLE` payload.
- Analysis exception: HTTP 503, state becomes `ANALYSIS_FAILED`, previous plan is cleared from current state.
- Template read failure: minimal fallback page is served and trading remains blocked.
---
## API Reference
### Base and authentication
All Futures routes are mounted on the existing Hermes FastAPI application and port. In production, use the Space base URL and an authenticated browser/session or HTTP Basic credentials.
When `HERMES_ADMIN_PASSWORD` is set, Futures API routes require:
```http
Authorization: Basic <base64(username:password)>
```
Default username: `admin`, configurable with `HERMES_DASHBOARD_BASIC_AUTH_USERNAME`.
All Futures responses set `Cache-Control: no-store`. `/futures` also sets no-cache headers and runtime SHA-256 headers.
### `GET /futures`
Returns the packaged HTML dashboard.
Important response headers:
```text
X-Hermes-Template-SHA256
X-Hermes-Router-SHA256
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
```
### `GET /api/futures/status`
Returns application status, runtime-file evidence, market health, latest bounded plan state, source metadata, account summary, and diagnostics.
Representative shape:
```json
{
"application": {
"status": "online",
"runtimeStatus": "verified | mismatch | unknown",
"runtimeFiles": {}
},
"marketData": {"status": "healthy | degraded | unavailable"},
"tradingReadiness": "ready | blocked",
"mergeStatus": "complete | partial | unknown",
"analysisState": "NOT_ANALYZED",
"sourceMetadata": {
"datasource4": {},
"binance": {},
"datasource2": {}
},
"fieldSources": {},
"fieldMetadata": {},
"verifiedFutures": false,
"missingRequiredFields": [],
"staleRequiredFields": [],
"latestTradePlan": null,
"latestPlanId": null,
"latestSignalScore": null,
"riskApproved": false,
"tradingMode": "paper",
"equity": 10000.0,
"realizedPnlToday": 0.0,
"openPositionCount": 0,
"serverTime": 0
}
```
Consumers should treat additional fields as additive and avoid strict whole-object equality.
### `GET /api/futures/symbols`
Returns the merged catalog.
```json
{
"symbols": [
{
"symbol": "BTCUSDT",
"baseAsset": "BTC",
"quoteAsset": "USDT",
"futuresVerified": true,
"marketOnly": false,
"contractType": "PERPETUAL",
"status": "TRADING",
"source": "datasource4",
"rank": 1,
"updatedAt": "2026-07-21T00:00:00Z"
}
],
"source": "...",
"updatedAt": "...",
"counts": {
"total": 0,
"verifiedFutures": 0,
"marketOnly": 0
}
}
```
Catalog membership alone does not authorize execution. Only items with `futuresVerified=true` are eligible for Paper revalidation.
### `GET /api/futures/positions`
Returns Paper mode and enriched open positions.
```json
{
"mode": "paper",
"positions": [
{
"symbol": "BTC/USDT:USDT",
"side": "long",
"size": 0.01,
"entryPrice": 60000.0,
"markPrice": 60500.0,
"unrealizedPnl": 5.0
}
]
}
```
Mark price enrichment is best-effort. Missing mark data produces `null`, not zero.
### `GET /api/futures/market`
Query parameters:
| Parameter | Type | Default | Constraints |
|---|---|---:|---|
| `symbol` | string | `BTCUSDT` | length 3–32; normalized server-side |
| `interval` | enum | `5m` | `1m`, `5m`, `15m`, `1h` |
| `limit` | integer | `120` | 20–500 |
Example:
```http
GET /api/futures/market?symbol=BTCUSDT&interval=5m&limit=120
```
Successful/partial shape:
```json
{
"state": "available | partial | stale | unavailable",
"analysisState": "NOT_ANALYZED | STALE | API_UNAVAILABLE",
"dataUsability": "usable | degraded | unavailable",
"reason": null,
"symbol": "BTCUSDT",
"interval": "5m",
"limit": 120,
"candles": [
{"timestamp": 0, "open": 0, "high": 0, "low": 0, "close": 0, "volume": 0}
],
"currentPrice": null,
"markPrice": null,
"change24h": null,
"volume24h": null,
"fundingRate": null,
"openInterest": null,
"source": "datasource4 | binance_public | datasource2 | mixed | unavailable",
"sourcesUsed": [],
"fieldSources": {},
"fieldMetadata": {},
"freshness": "fresh | stale | invalid | unknown",
"verifiedFutures": false,
"futuresVerification": {},
"warnings": [],
"missingFields": [],
"analysisRequiredFieldsMissing": [],
"staleRequiredFields": [],
"mergeStatus": "complete | partial | unavailable",
"tradingReadiness": "ready | blocked",
"rejectionReasons": [],
"sourceMetadata": {},
"technicalDiagnostics": {},
"fetchedAt": 0
}
```
If acquisition raises, the route returns HTTP `503` with the same high-level keys, empty candles, null values, `state=unavailable`, `analysisState=API_UNAVAILABLE`, and blocked readiness.
No mock candles are permitted in production responses.
### `POST /api/futures/analyze`
Request:
```json
{
"symbol": "BTCUSDT",
"risk_profile": "moderate",
"include_external_context": false
}
```
Allowed risk profiles:
```text
conservative
moderate
aggressive
```
Unknown request fields are rejected.
Representative response:
```json
{
"planId": "server-generated-reference",
"symbol": "BTCUSDT",
"decision": "LONG | SHORT | NO_TRADE",
"analysis_state": "LONG | SHORT | NO_TRADE",
"score": null,
"confidence": null,
"components": {},
"core_reasons": [],
"warnings": [],
"entry": null,
"stop_loss": null,
"take_profit": null,
"reward_to_risk": null,
"risk_profile": "moderate",
"risk_percent": null,
"requested_leverage": 5,
"effective_leverage": null,
"quantity": null,
"estimated_slippage_percent": null,
"risk_approved": false,
"rejection_reasons": [],
"noTradeGuard": true,
"plan_type": "directional_plan | non_executable_plan",
"executable": false,
"futuresVerified": false,
"trading_readiness": "blocked",
"created_at": "...",
"expires_at": "...",
"external_advisory": null
}
```
A `NO_TRADE` response is a successful deterministic evaluation, not an HTTP failure. An internal analysis failure returns HTTP `503` with `detail="Futures analysis failed"` and clears the current plan state.
### `POST /api/futures/paper/execute`
Request:
```json
{
"symbol": "BTCUSDT",
"risk_profile": "moderate",
"planId": "server-generated-reference"
}
```
The endpoint may return:
- `403` for unverified contract or non-Paper mode;
- `409` for superseded/unknown plan, symbol/risk change, expiry, prior execution, blocked readiness, failed fresh revalidation, or non-executable plan;
- `422` for invalid request shape/symbol;
- `200` for the final Paper result.
The endpoint is intentionally absent from the read-only audit tool.
### Telegram routes
#### `POST /api/telegram/webhook`
Public webhook ingress protected by:
```http
X-Telegram-Bot-Api-Secret-Token: <TELEGRAM_WEBHOOK_SECRET>
```
Limits request body to 256 KiB, applies per-user rate limiting, requires owner/allowed-user authorization, and invokes analysis-only commands.
#### `GET /api/telegram/status`
Returns enabled/mode/webhook/proxy/relay/authorized-user/alert-scheduler status. It does not expose tokens or user IDs.
#### `GET /api/telegram/bootstrap/status`
Requires the same Telegram secret header and returns only:
```json
{"ok": true, "ownerClaimed": true, "bootstrapConsumed": true}
```
---
## Datasource Pipeline and Contracts
### Priority and authority
```text
Datasource 4 → Binance public fallback → Datasource 2
```
Priority describes fill order, not equal trust.
#### Datasource 4
Authoritative for:
- Futures contract verification;
- `dataState`;
- `noTradeGuard`;
- safety status and rejection reasons;
- primary Futures market fields.
#### Binance public
- unauthenticated;
- called only for missing, unusable, or stale fields;
- cannot verify a contract or clear DS4 safety;
- HTTP 451 is `restricted` / `Regionally restricted`;
- provider timestamps are required to claim freshness.
#### Datasource 2
- complementary news, sentiment, indicator, order-book, volume, trending, gainers, and correlation context;
- may fill a still-missing legitimate field only after Binance;
- cannot become Futures verification or safety authority.
### Datasource 4 request
The DS4 snapshot endpoint is called with:
```text
/api/short-hunter/snapshot/{SYMBOL}
```
Parameters:
```text
interval: 1m | 5m | 15m | 1h
limit: 1..500 internally; market API exposes 20..500
from: epoch milliseconds
to: epoch milliseconds
```
`normalize_epoch_milliseconds()` accepts contemporary epoch seconds or milliseconds and prevents double conversion. `build_kucoin_time_range()` enforces supported interval, bounded limit, positive ordered timestamps, and millisecond units.
### Normalized fields
The merged envelope may contain:
```text
contract
ticker
ohlcv
orderbook
funding
openInterest
indicators
sentiment
atr
market_context
```
#### Contract
Normalized contract data should expose symbol, status, type/instrument, and explicit verification evidence when present. The presence of a generic `contract` object alone does not prove Futures status. Verification requires an explicit DS4 flag or a recognized Futures/perpetual/swap contract type.
#### Ticker
Accepted aliases are normalized to a bounded ticker object. Consumers should prefer normalized canonical keys where available and tolerate provider-specific supplemental keys.
Common price candidates:
```text
markPrice
lastPrice
last
price
close
indexPrice
```
#### OHLCV
Canonical candle shape:
```json
{
"timestamp": 0,
"open": 0.0,
"high": 0.0,
"low": 0.0,
"close": 0.0,
"volume": 0.0
}
```
A usable OHLCV series requires at least four valid positive close values. The market endpoint never invents missing candles.
#### Order book
Canonical shape:
```json
{
"bids": [[60000.0, 0.5]],
"asks": [[60001.0, 0.4]],
"timestamp": 0
}
```
Both sides must have at least one valid level. Prices must be positive; quantities must be non-negative.
#### Funding
Canonical values may include:
```text
currentFundingRate
fundingRate
lastFundingRate
rate
nextFundingTime
```
#### Open Interest
Canonical values may include:
```text
openInterest
sumOpenInterest
oi
changeFraction
change24h
changePercent
```
### Field usability
`_is_usable(field, value)` performs field-specific validation. Empty values, non-finite values, invalid OHLCV, incomplete order books, and invalid contract/funding/OI shapes are rejected.
### Per-field provenance
Every owned field receives metadata:
```json
{
"value": "bounded or summarized value",
"source": "datasource4 | binance_public | datasource2 | unavailable",
"timestamp": "provider timestamp or null",
"freshness": "fresh | stale | invalid | unknown",
"validity": "valid | unavailable",
"observedAt": "server observation time",
"freshnessBasis": "field_timestamp | datasource4_dataState | missing_provider_timestamp | unavailable",
"fallbackStatus": "primary | fallback | not_filled"
}
```
The public API bounds large values:
- OHLCV becomes count plus latest candle summary where appropriate;
- order book becomes level counts and best bid/ask summary;
- diagnostics are sanitized and size-limited.
### Freshness
Freshness is based on provider timestamp relative to interval, or on an explicit authoritative DS4 fresh state. Transport success alone is not freshness evidence.
Required fields with `stale`, `invalid`, or `unknown` freshness block readiness.
### Critical fields and readiness
Critical fields:
```text
contract
ticker
orderbook
funding
openInterest
```
The combined context sets:
```text
missingRequiredFields
staleRequiredFields
noTradeGuard
noTradeReasons
mergeStatus
tradingReadiness
```
Readiness is `ready` only when no guard remains. DS4 verification failure, DS4 `noTradeGuard`, missing critical fields, or non-fresh critical fields results in `blocked`.
### Source metadata
Each source returns structured fields:
```json
{
"name": "Datasource 4",
"url": "...",
"status": "ok | degraded | unreachable | unavailable | standby",
"transportStatus": "healthy | degraded | unavailable | restricted | standby",
"dataUsability": "usable | degraded | unavailable | not_used",
"endpoint": "...",
"httpStatus": 200,
"latencyMs": 120.4,
"lastSuccess": "...",
"freshness": "fresh | stale | unknown",
"completeness": "complete | partial | unknown",
"suppliedFields": [],
"missingFields": [],
"reason": "concise operator-facing summary"
}
```
Detailed endpoint/provider errors belong only under `technicalDiagnostics`, separated by source and sanitized before exposure.
### Merge diagnostics
Cross-source problems are not assigned to a datasource card. They appear under:
```text
technicalDiagnostics.merge.status
technicalDiagnostics.merge.missingCriticalFields
technicalDiagnostics.merge.tradingReadiness
technicalDiagnostics.merge.rejectionReasons
```
### Adding a new provider mapping
1. Capture a real redacted payload.
2. Add the narrowest legitimate alias to the relevant normalizer.
3. Preserve provider timestamp and source name.
4. Add field-specific validity checks.
5. Do not infer Futures verification from generic market data.
6. Do not let the provider clear DS4 guard state.
7. Add focused tests for positive, missing, malformed, stale, and ambiguous cases.
8. Verify source-specific diagnostics remain correctly attributed.
---
## Frontend Guide
### File and runtime
The entire Futures dashboard UI is packaged in:
```text
hermes_overlay/tools/templates/hermes_futures_desk_luxury.html
```
The router reads this file at request time from its installed `tools/templates` directory and serves it at `/futures`. Do not add a second frontend server, bundler process, or port.
### Design system
The UI uses an Obsidian & Gold workstation theme with a light-theme option. Operational values use readable sans-serif/monospace styling. Decorative serif/italic styling is limited to headings and visual accents.
Responsive modes cover desktop, tablet, and mobile. `prefers-reduced-motion` is respected.
### Main UI regions
- fixed/collapsible navigation and local market lists;
- command deck with symbol, risk, advisory, Analyze, and Paper Execute controls;
- selected-market header and chart;
- market diagnostics and field provenance;
- decision, score, risk approval, and execution mode;
- trade-plan geometry and execution checklist;
- signal reasons and components;
- Paper account and positions;
- datasource health and technical diagnostics;
- Telegram operational status;
- local activity/history and export actions.
### API usage
The helper uses:
```javascript
fetch(url, {
credentials: 'same-origin',
cache: 'no-store'
})
```
Primary calls:
```text
GET /api/futures/status
GET /api/futures/symbols
GET /api/futures/positions
GET /api/futures/market
POST /api/futures/analyze
POST /api/futures/paper/execute
GET /api/telegram/status
```
No backend route is declared in the template.
### Refresh behavior
Default intervals:
- clock and age labels: 1 second;
- status and positions: 5 seconds while auto-refresh is enabled and page is visible;
- market data: 15 seconds;
- Telegram status: 60 seconds.
When the page becomes visible again, status and market data refresh if automatic refresh is enabled.
### Chart behavior
Supported intervals:
```text
1m 5m 15m 1h
```
Supported candle limits:
```text
60 120 240
```
Modes:
- Candles;
- Line;
- optional volume bars.
The chart is an inline SVG and uses only `candles` returned by the market endpoint. Crosshair, OHLCV legend, tooltip, current-price reference, price labels, visible high/low, range position, and last-candle age are derived from the returned series.
No visual interpolation or fallback is permitted to create production candles.
### Display-only diagnostics
The UI calculates visible trend, average candle range, relative last-candle volume, realized variation, last-candle direction, and range position from the real returned candles. These values are explicitly informational and must never change:
```text
LONG / SHORT / NO_TRADE
risk approval
noTradeGuard
Entry / SL / TP
leverage
quantity
execution eligibility
```
### Local browser state
The UI stores only convenience preferences/history in `localStorage`.
Known keys:
```text
hermes_theme
hermes_auto_refresh
hermes_compact
```
Watchlist, recent markets, local analysis history, and workspace activity use Hermes-prefixed local keys defined in the template. They are not synchronized to the server and are not trusted for execution.
### Keyboard shortcuts
| Key | Action |
|---|---|
| `/` | Focus and select symbol search. |
| `A` | Run analysis when not already analyzing. |
| `R` | Manual refresh. |
| `D` | Toggle display density. |
| `T` | Toggle theme. |
| `?` | Open shortcut help. |
| `Escape` | Close overlays/help. |
There is deliberately no keyboard shortcut for Paper Execute.
### Analysis state rendering
Use the server result to set one of:
```text
NOT_ANALYZED
ANALYZING
LONG
SHORT
NO_TRADE
ANALYSIS_FAILED
STALE
API_UNAVAILABLE
```
Important rules:
- initial state is “Waiting for analysis,” not `NO_TRADE`;
- HTTP/network failure is `ANALYSIS_FAILED` or `API_UNAVAILABLE`;
- score is “Unavailable” when components do not exist, not numeric zero;
- expiry is prominent only for a valid directional plan;
- rejected/incomplete analysis is not presented as executable;
- changing symbol or risk invalidates the current browser plan;
- server state remains authoritative.
### Execute availability
The button is disabled unless the latest browser plan mirrors all required server fields. The UI displays a concrete disabled reason such as:
```text
Run analysis first
No directional plan
Risk approval failed
noTradeGuard active
Market-only symbol
Plan expired
Symbol changed
Risk profile changed
Plan already executed
Required Futures fields unavailable
```
These checks improve UX but do not replace backend revalidation.
### Adding a UI feature safely
1. Reuse existing API fields or add an additive backend field.
2. Render missing values as `Unavailable`, never zero or fabricated content.
3. Keep browser calculations labeled display-only.
4. Do not add another Execute path or shortcut.
5. Invalidate plan display when relevant controls change.
6. Keep DOM IDs unique and update static ID checks.
7. Preserve responsive and reduced-motion behavior.
8. Do not display raw provider errors or secrets.
9. Verify Console and Network in an authenticated deployed session.
---
## Environment Configuration
Configure secrets in Hugging Face Space Settings or inject them at container runtime. Never commit a populated `.env` file.
### Core persistence
| Variable | Default | Purpose |
|---|---|---|
| `HF_TOKEN` | none | Hugging Face token with required repository access. |
| `HERMES_DATASET_REPO` | derived/none | Private Dataset used to persist `/opt/data`. |
| `AUTO_CREATE_DATASET` | `true` | Create the private Dataset when missing. |
| `SYNC_INTERVAL` | `60` | Persistence sync interval in seconds. |
| `HF_HUB_DOWNLOAD_TIMEOUT` | implementation default | Hub download timeout. |
| `HF_HUB_UPLOAD_TIMEOUT` | implementation default | Hub upload timeout. |
| `HERMES_HOME` | `/opt/data` | Persistent Hermes data root. |
| `MAX_BACKUPS` | script default | Backup retention used by persistence helper. |
### Dashboard authentication
| Variable | Default | Purpose |
|---|---|---|
| `HERMES_ADMIN_PASSWORD` | none | Required production dashboard password. |
| `HERMES_ADMIN_USERNAME` | `admin` | Username written to Hermes dashboard config by entrypoint. |
| `HERMES_DASHBOARD_BASIC_AUTH_USERNAME` | `admin` | Username checked by Futures router and runtime audit. |
For the audit tool only:
| Variable | Purpose |
|---|---|
| `HERMES_DASHBOARD_COOKIE` | Existing authenticated session cookie when Basic auth is not used. |
| `HERMES_FUTURES_BASE_URL` | Default audit target base URL. |
### Datasources
| Variable | Default | Purpose |
|---|---|---|
| `DS4_BASE_URL` | DS4 Hugging Face Space URL | Authoritative Datasource 4 base. |
| `DS4_TIMEOUT_S` | `6` | DS4 request timeout. |
| `DS2_BASE_URL` | DS2 Hugging Face Space URL | Complementary Datasource 2 base. |
| `DS2_TIMEOUT_S` | `6` | DS2 request timeout. |
| `HERMES_SYMBOL_CACHE_PATH` | `/opt/data/futures_symbols_cache.json` | Symbol catalog cache. |
### Binance fallback
| Variable | Default | Purpose |
|---|---|---|
| `BINANCE_PUBLIC_FALLBACK_ENABLED` | `true` | Enable unauthenticated field fallback. |
| `BINANCE_FUTURES_PUBLIC_BASE_URL` | `https://fapi.binance.com` | Binance Futures public base. |
| `BINANCE_FUTURES_TIMEOUT_S` | `5` | Request timeout. |
| `BINANCE_FUTURES_MAX_RETRIES` | `2` | Retry bound. |
| `BINANCE_KLINE_INTERVAL` | `5m` | Default fallback interval. |
| `BINANCE_KLINE_LIMIT` | `100` | Default kline count. |
| `BINANCE_ATR_PERIOD` | `14` | ATR lookback in fallback client. |
| `BINANCE_ORDERBOOK_LIMIT` | `20` | Depth level limit. |
| `BINANCE_OI_PERIOD` | `5m` | Open Interest history period. |
A regional HTTP 451 must be surfaced honestly. Do not use raw IP, DNS bypass, or TLS bypass.
### Deterministic analysis
| Variable | Default | Purpose |
|---|---:|---|
| `FUTURES_MIN_SIGNAL_SCORE` | `0.55` | Minimum absolute deterministic score. |
| `FUTURES_MIN_SIGNAL_COMPONENTS` | `3` | Minimum present scoring components. |
| `FUTURES_MIN_DIRECTION_CONFIRMATIONS` | `2` | Minimum components confirming direction. |
| `FUTURES_STOP_ATR_MULTIPLIER` | `1.2` | ATR stop-distance multiplier. |
| `FUTURES_TAKE_PROFIT_RR` | `1.8` | Target reward-to-risk. |
| `FUTURES_MIN_STOP_BPS` | `20` | Minimum stop distance in basis points. |
| `FUTURES_PLAN_MAX_AGE_SECONDS` | `20` | Plan expiry window. |
| `FUTURES_DEFAULT_LEVERAGE` | `5` | Requested leverage before caps/haircut. |
Changing these variables changes deterministic behavior and requires explicit review, tests, and deployment evidence.
### Execution and Paper account
| Variable | Default | Purpose |
|---|---|---|
| `PAPER_EQUITY_USDT` | implementation default | Initial Paper account equity. |
| `FUTURES_EXCHANGE_ID` | implementation default | Exchange adapter ID. |
| `FUTURES_API_KEY` | none | Exchange credential boundary. Do not set for routine Paper-only development. |
| `FUTURES_API_SECRET` | none | Exchange secret. |
| `FUTURES_API_PASSPHRASE` | none | Optional exchange passphrase. |
Do not introduce credentials into source, logs, diagnostics, screenshots, patches, or generated reports.
### External advisory
| Variable | Default | Purpose |
|---|---|---|
| `EXTERNAL_AI_ENABLED` | `true` | Allow advisory when explicitly requested. |
| `EXTERNAL_AI_TIMEOUT_SECONDS` | `8` | Legacy/advisory timeout. |
| `EXTERNAL_AI_PROVIDER_TIMEOUT_SECONDS` | `8` | Per-provider timeout. |
| `EXTERNAL_AI_TOTAL_TIMEOUT_SECONDS` | `15` | Total advisory budget. |
| `OPENROUTER_ANALYSIS_MODEL` | configured model | OpenRouter model. |
| `GOOGLE_ANALYSIS_MODEL` | configured model | Google model. |
| `HF_ANALYSIS_MODEL` | configured model | Hugging Face model. |
| `OPENROUTER_API_KEY` | none | OpenRouter credential. |
| `GOOGLE_API_KEY` | none | Google credential. |
Provider order is OpenRouter → Google → Hugging Face. Advisory output cannot change the deterministic plan.
### Telegram webhook
| Variable | Default | Purpose |
|---|---|---|
| `TELEGRAM_ENABLED` | `false` | Enable webhook adapter. |
| `TELEGRAM_MODE` | `webhook` | Must remain webhook mode. |
| `TELEGRAM_PUBLIC_BASE_URL` | Space URL | Webhook target base. |
| `TELEGRAM_WEBHOOK_PATH` | `/api/telegram/webhook` | Webhook path. |
| `TELEGRAM_WEBHOOK_SECRET` | none | Telegram secret-token header value. |
| `TELEGRAM_BOOTSTRAP_SECRET` | none | One-time owner claim secret. |
| `TELEGRAM_ALLOWED_USER_IDS` | empty | Comma-separated authorized IDs. |
| `TELEGRAM_BOT_TOKEN` | none | Telegram bot token. |
| `TELEGRAM_PROXY_URL` | empty | Optional direct Bot API proxy. |
| `TELEGRAM_RELAY_URL` | empty | Optional proactive relay. |
| `TELEGRAM_RELAY_SECRET` | empty | HMAC relay secret. |
| `TELEGRAM_STATE_PATH` | `/opt/data/telegram_state.json` | Persisted owner/watchlist state. |
| `TELEGRAM_ALERTS_ENABLED` | `false` | External-scheduler alert evaluation status. |
| `TELEGRAM_COMMAND_RATE_LIMIT` | `10` | Commands per user per minute. |
| `TELEGRAM_SCAN_MAX_SYMBOLS` | `300` | Maximum verified catalog candidates. |
| `TELEGRAM_SCAN_SHORTLIST_SIZE` | `20` | Deterministic shortlist size. |
| `TELEGRAM_SCAN_RESULT_COUNT` | `10` | Displayed result count. |
| `TELEGRAM_SCAN_MAX_CONCURRENCY` | `4` | Analysis concurrency. |
### MCP isolation
| Variable | Default | Requirement |
|---|---|---|
| `LINEAR_MCP_ENABLED` | `false` | Keep unchanged unless separately approved. |
| `UNREAL_ENGINE_MCP_ENABLED` | `false` | Keep disabled unless separately approved. |
### Runtime integrity paths
Advanced overrides used by diagnostics:
```text
HERMES_FUTURES_OVERLAY_MANIFEST
HERMES_OVERLAY_SOURCE
HERMES_SYNC_SCRIPT
```
These should normally use their runtime defaults.
---
## Deployment Runbook
### Preconditions
- Work from the current repository under `asset-space`.
- Review all diffs.
- Ensure no real `.env`, tokens, cookies, screenshots, cache, ZIP archives, runtime reports, or temporary probes are staged.
- Confirm no architecture change introduces a second app, frontend server, or port.
- Do not execute a trade during deployment verification.
### Build behavior
The Dockerfile:
1. clones upstream Hermes Agent into `/opt/hermes`;
2. installs Node, web dashboard, Playwright, Python, CCXT, and HTTPX dependencies;
3. creates non-root user `hermes` and `/opt/data` directories;
4. copies scripts into `/opt/data/scripts`;
5. copies overlay into `/opt/data/hermes_overlay` and immutable `/opt/hermesface_overlay`;
6. starts `/opt/data/scripts/entrypoint.sh`.
### Startup behavior
`entrypoint.sh`:
1. starts DNS pre-resolution in the background;
2. activates `/opt/hermes/.venv`;
3. creates persistent directories and baseline config files;
4. writes hashed dashboard Basic auth when `HERMES_ADMIN_PASSWORD` is configured;
5. calls `scripts/sync_hf.py`.
`sync_hf.py`:
1. restores persistent data when configured;
2. disables legacy Telegram gateway polling in webhook mode;
3. installs the current image overlay into `/opt/hermes`;
4. writes and verifies the overlay hash manifest;
5. mounts Futures and Telegram routers into the existing dashboard app;
6. starts Hermes dashboard on port `7860`;
7. manages persistence/sync helpers.
### Hugging Face deployment procedure
1. Review the final diff.
2. Commit the smallest coherent change.
3. Push to `main` of the repository backing `Really-amin/Asset`.
4. Monitor Space build logs.
5. Wait until Space is fully `RUNNING`.
6. Record the serving repository revision.
7. Run the read-only runtime audit.
8. Open an authenticated browser session.
9. Inspect Console and Network.
10. Verify Telegram status and MCP isolation.
### Read-only runtime audit
```bash
export HERMES_ADMIN_PASSWORD='...'
export HERMES_DASHBOARD_BASIC_AUTH_USERNAME='admin'
python scripts/verify_futures_runtime.py \
--base-url https://really-amin-asset.hf.space \
--symbol BTCUSDT \
--analyze \
--report .runtime_audit/futures_runtime_audit.json
```
Expected properties:
- `/futures` returns 200;
- body SHA-256 equals `X-Hermes-Template-SHA256`;
- status, symbols, and positions return authenticated 200 responses;
- each market interval returns 200 or structured 503;
- market payload shape includes real canonical candle objects;
- optional analysis returns 200;
- `paperExecuteCalled` remains false.
### Browser verification
Check:
- no critical JavaScript error;
- authenticated API requests are not redirected to login HTML;
- `/api/futures/market` is requested for each selected interval;
- chart code executes and state messages match payload;
- no stale cached template is served;
- selected-market header, provenance, diagnostics, plan, account, and datasource sections render;
- Execute remains disabled unless a valid server plan exists;
- do not click Execute.
### Runtime file verification
Use `/api/futures/status` and `/futures` response headers to compare:
```text
repository/image overlay template
repository/image overlay router
installed /opt/hermes template
installed /opt/hermes router
served HTML body
installation manifest
```
Interpretation:
- `verified`: all available expected files match;
- `mismatch`: at least one available expected hash differs;
- `unknown`: evidence is missing; investigate filesystem/install path.
### Rollback
1. Identify the last known healthy commit.
2. Revert only the faulty change; do not copy old reference directories over the current backend.
3. Push the revert.
4. Wait for Space rebuild and `RUNNING` state.
5. Repeat runtime audit and browser verification.
6. Confirm deterministic thresholds, Telegram webhook-only mode, and port 7860 remain unchanged.
### Release evidence to retain
- commit hash;
- serving Space revision;
- sanitized audit JSON;
- static/focused/regression test summary;
- runtime hash result;
- Console/Network findings;
- provider limitations such as Binance 451;
- explicit statement that no secret was exposed and no trade was executed.
---
## Security and Safety
### Non-negotiable invariants
Do not change or weaken:
- deterministic `LONG`, `SHORT`, and `NO_TRADE` decisions;
- Datasource 4 authority;
- `noTradeGuard`;
- Futures verification;
- provider timestamp and freshness checks;
- risk approval;
- Stop Loss and Take Profit rules;
- leverage caps and volatility haircut;
- quantity/sizing logic;
- Paper execution validation;
- Telegram webhook-only isolation;
- single FastAPI application and port 7860 architecture.
### Browser trust model
The browser is untrusted for execution. It may display and calculate convenience diagnostics, but the server ignores browser-derived authorization.
Server-side Paper checks include plan reference, symbol/risk identity, expiry, executed flag, direction, DS4 verification, readiness, guard state, risk approval, executable flag, Paper mode, and fresh re-analysis.
### Secret handling
Never expose or commit:
```text
HF_TOKEN
HERMES_ADMIN_PASSWORD
FUTURES_API_KEY
FUTURES_API_SECRET
FUTURES_API_PASSPHRASE
OPENROUTER_API_KEY
GOOGLE_API_KEY
TELEGRAM_BOT_TOKEN
TELEGRAM_WEBHOOK_SECRET
TELEGRAM_BOOTSTRAP_SECRET
TELEGRAM_RELAY_SECRET
cookies or Authorization headers
```
Diagnostics redact keys and text matching authorization, cookie, token, secret, password, or API key patterns. Continue to sanitize new error fields before they reach API responses or UI.
### Market-data integrity
- No fabricated production candles, prices, funding, Open Interest, or order-book levels.
- Missing values are `null`/`Unavailable`, not zero.
- HTTP success is not data freshness.
- Provider errors in main UI are concise; detailed errors remain sanitized under Technical Diagnostics.
- Binance regional restriction must not be bypassed with raw IP, DNS override, or disabled TLS.
### External AI boundary
External AI may return market bias, confidence, summary, and warnings. It must never modify:
```text
decision
risk approval
noTradeGuard
Entry
Stop Loss
Take Profit
leverage
quantity
execution availability
```
Bulk scans must not use advisory AI.
### Telegram boundary
- Webhook secret-token validation is mandatory.
- Request size is bounded.
- Owner bootstrap is one-time, secret-checked, and private-chat only.
- Users are authorized by configured IDs or persisted owner.
- Commands are rate-limited.
- Callback nonces expire and are user-bound.
- Telegram performs analysis only and contains no order path.
- Polling remains disabled.
### Development safety
During ordinary development and deployment verification:
- do not call Paper Execute;
- do not run Testnet or Live execution;
- use the read-only audit script;
- use Paper account endpoints only for display verification;
- do not add an execution keyboard shortcut;
- do not allow a UI feature to write plan or risk state directly.
### Review checklist for security-sensitive changes
- Does the change alter a deterministic threshold or formula?
- Can fallback data override DS4 safety?
- Can a missing timestamp be treated as fresh?
- Can the browser enable execution without server state?
- Can a raw error include a secret?
- Can a Telegram request bypass authorization or webhook validation?
- Does the change introduce a second network service or port?
- Does it add an exchange credential requirement?
- Are failure states blocked by default?
---
## Operations and Troubleshooting
### Diagnostic order
1. Confirm Space is `RUNNING`.
2. Fetch `/futures` and inspect response/hash headers.
3. Check `/api/futures/status` with authentication.
4. Inspect runtime file status and datasource metadata.
5. Check Browser Console and Network.
6. Inspect market endpoint for one symbol/interval.
7. Compare DS4 raw/normalized fields and timestamps.
8. Check provider-specific diagnostics.
9. Run one analysis-only request.
10. Do not test Paper Execute during diagnosis.
### Common issues
#### Dashboard returns 401
Likely causes:
- missing/incorrect `HERMES_ADMIN_PASSWORD`;
- wrong Basic username;
- browser session expired;
- reverse proxy did not preserve auth.
Actions:
- confirm `HERMES_ADMIN_USERNAME` and `HERMES_DASHBOARD_BASIC_AUTH_USERNAME` alignment;
- re-authenticate;
- verify `entrypoint.sh` logged successful auth configuration;
- never print the password in logs or reports.
#### `/futures` returns 200 but old UI appears
Possible causes:
- stale installed overlay;
- wrong template path;
- restored old overlay taking precedence;
- CDN/browser cache;
- duplicate old page implementation.
Actions:
- compare `X-Hermes-Template-SHA256` with body hash;
- inspect `application.runtimeFiles` in status;
- confirm `/opt/hermesface_overlay` is preferred;
- confirm installed `/opt/hermes/tools/templates/...` matches manifest;
- hard reload only after server-side evidence is checked.
#### Runtime status is `unknown`
`unknown` means evidence is absent, not that files match.
Actions:
- verify manifest path and permissions;
- verify overlay and runtime paths exist;
- check `HERMES_FUTURES_OVERLAY_MANIFEST`, `HERMES_OVERLAY_SOURCE`, and `HERMES_SYNC_SCRIPT` overrides;
- inspect overlay installation logs.
#### Runtime status is `mismatch`
Actions:
- identify exact mismatched file in status payload;
- compare repository/image overlay and `/opt/hermes` file;
- verify `sync_hf.py` installed after persistence restore;
- rebuild/redeploy from a clean commit.
#### Chart says market data unavailable
Check market endpoint payload:
- HTTP 503 and `API_UNAVAILABLE`: acquisition exception;
- `state=unavailable`: no real candles/current price;
- `state=stale`: provider timestamp invalid or stale;
- `state=partial`: freshness unknown or display fields incomplete.
Inspect:
```text
warnings
missingFields
analysisRequiredFieldsMissing
staleRequiredFields
sourceMetadata
technicalDiagnostics
```
Do not replace missing candles with mock data.
#### Binance shows HTTP 451
This is an expected regional limitation in some Hugging Face regions.
Correct behavior:
```text
transportStatus=restricted
httpStatus=451
dataUsability=unavailable
reason=Regionally restricted
```
Do not use raw-IP or TLS-bypass workarounds. DS4 safety remains authoritative.
#### KuCoin reports “Parameter 'from' must be milliseconds”
Verify DS4 request builder uses `build_kucoin_time_range()` and sends integer millisecond `from` and `to`. Check for upstream code that converts an already-millisecond value a second time.
#### Market data is HTTP 200 but readiness is blocked
Transport and readiness are separate. Inspect:
- DS4 Futures verification;
- DS4 `noTradeGuard`;
- missing critical fields;
- non-fresh critical fields;
- merge rejection reasons.
A provider may be reachable while its data is unusable.
#### `NO_TRADE` displayed before analysis
The initial state must be `NOT_ANALYZED`. Check frontend initialization and `/api/futures/status.analysisState`. A network error must be `ANALYSIS_FAILED` or `API_UNAVAILABLE`, not `NO_TRADE`.
#### Signal score shows zero with no components
The UI must show `Unavailable`. Check whether `latestSignalScore` is `null` and whether signal components are empty. Do not coerce null to zero.
#### Execute button is disabled
This is normally correct. Read the visible reason and inspect:
```text
latest plan exists
planId matches
symbol and risk match
plan not expired
LONG/SHORT decision
verified Futures
risk approved
noTradeGuard false
tradingReadiness ready
executable true
not already executed
```
#### Telegram says Owner setup required
No configured/persisted owner exists. Use the one-time private `/claim <TELEGRAM_BOOTSTRAP_SECRET>` flow. Remove/rotate the bootstrap secret after claim. Do not expose owner ID in dashboard status.
#### Telegram proactive alerts unavailable
Webhook responses can work without outbound connectivity, but proactive alerts need either:
- direct Telegram access with optional proxy; or
- configured relay URL and HMAC secret.
Keep polling disabled.
### Logs and artifacts
Useful logs:
```text
Space build log
entrypoint startup log
sync_hf overlay install/hash log
Hermes dashboard log under /opt/data/logs
sanitized runtime audit JSON
browser Console and Network export without credentials
```
Never attach raw cookies, Authorization headers, tokens, or unredacted provider payloads.
---
## Testing and Verification
### Test locations
```text
hermes_overlay/tests/
```
Existing focused areas include:
- Binance public fallback;
- nested DS4 merge behavior;
- external advisory boundary;
- Futures dashboard/state;
- Futures integration;
- Luxury template markers;
- optional MCP runtime isolation;
- Telegram webhook;
- trade-cycle field paths.
### Recommended validation layers
#### 1. Static validation
```bash
python -m compileall hermes_overlay scripts
node --check /tmp/hermes_dashboard_script.js
ruff check hermes_overlay scripts
```
Also check:
- duplicate DOM IDs;
- missing JavaScript DOM references;
- undefined CSS custom properties;
- `git diff --check`;
- absence of secrets/generated files.
#### 2. Focused unit tests
Required focus:
- seconds-to-milliseconds conversion;
- already-millisecond timestamps;
- ordered bounded KuCoin ranges;
- ticker/funding/Open Interest aliases;
- malformed and ambiguous provider shapes;
- per-field source/timestamp/freshness attribution;
- transport health versus usability/readiness;
- datasource-specific error attribution;
- market endpoint canonical shape;
- no fabricated values;
- safe rejection when required fields are missing or non-fresh;
- initial/failure UI states;
- Execute-disabled reasons and server safety gates.
#### 3. Futures regression suite
Run the existing Futures tests once after focused tests pass. Avoid repeatedly running unrelated broad suites while iterating on a narrow failure.
#### 4. Read-only deployed audit
```bash
export HERMES_ADMIN_PASSWORD='...'
python scripts/verify_futures_runtime.py \
--base-url https://really-amin-asset.hf.space \
--symbol BTCUSDT \
--analyze \
--report .runtime_audit/futures_runtime_audit.json
```
The audit never calls Paper Execute.
#### 5. Browser verification
Authenticated desktop and mobile verification must cover:
- Console free of critical errors;
- valid Network status and JSON payloads;
- chart rendering for all intervals;
- Candles/Line, volume, tooltip, crosshair;
- watchlist/recent/history/export/density/theme/auto-refresh controls;
- field provenance and datasource cards;
- state machine and score semantics;
- visible Execute-disabled reason;
- no Paper Execute click.
### Acceptance matrix
| Area | Required result |
|---|---|
| Runtime files | `verified`, or documented investigation for `unknown`; never unexplained mismatch. |
| Status API | 200 authenticated, structured source/runtime fields. |
| Symbols API | Accurate total/verified/market-only counts. |
| Positions API | Deliberate empty state or formatted real Paper positions. |
| Market API | Real canonical candles or explicit structured unavailable state. |
| Analysis API | Deterministic result; `NO_TRADE` is allowed and expected when unsafe. |
| Paper Execute | Not called during verification. |
| Binance 451 | Clearly reported as regional restriction. |
| Telegram | Webhook-only; no polling adapter. |
| Secrets | None in source, logs, reports, screenshots, or package. |
### Testing safety
Tests must not:
- place Paper/Testnet/Live orders;
- require real exchange credentials;
- fabricate production responses in deployed paths;
- weaken guards to make assertions pass;
- treat an unavailable score as zero;
- report missing runtime evidence as verified.
---
## Contributing
### Change policy
- Work from the current repository implementation, not old loose reference files.
- Keep API changes additive and backward-compatible.
- Keep the existing Hermes application and port 7860.
- Prefer focused changes with explicit ownership boundaries.
- Do not accept “implemented” without code review, tests, and deployed evidence.
### Coding style
Python configuration:
```text
Python target: 3.10+
line length: 120
formatter: Black
lint: Ruff
```
The runtime image currently uses a newer Python version, but overlay code should remain compatible with the configured project target unless deliberately changed.
### Module ownership
- Acquisition/normalization/provenance: `dual_datasource_client.py`.
- Binance-only HTTP/normalization: `binance_public_client.py`.
- Signal/plan orchestration: `trade_cycle.py`.
- Risk formulas: `risk.py`.
- Execution behavior: `futures_execution.py`.
- Bounded dashboard memory: `state.py`.
- HTTP contracts/runtime diagnostics: `futures_dashboard_api.py`.
- Visual/UI behavior: Luxury template.
- Webhook-only Telegram: `telegram_bot.py`.
- Overlay installation/process startup: `sync_hf.py`.
Do not duplicate logic across layers.
### Adding a field
1. Define the legitimate source and authority.
2. Add narrow normalization aliases.
3. Add field validity rules.
4. Preserve source, provider timestamp, freshness, and fallback status.
5. Add the field to public bounded metadata only if safe.
6. Add additive API output.
7. Render missing value as `Unavailable`.
8. Add focused tests.
### Changing deterministic logic
A change to score thresholds, weights, SL/TP, leverage, risk profile, sizing, slippage threshold, or expiry is safety-sensitive. The pull request must include:
- motivation;
- before/after behavior;
- test coverage;
- risk analysis;
- confirmation that DS4 authority and guard behavior remain intact;
- production verification plan.
### Frontend contributions
- Keep a single template and existing route.
- Avoid duplicate DOM IDs.
- Avoid undefined CSS variables.
- Preserve keyboard accessibility and reduced motion.
- Never add a second Execute path or an execution shortcut.
- Do not trust localStorage for plan authorization.
- Keep raw errors out of primary cards.
### Commit hygiene
Do not stage:
```text
.env
credentials
cookies
tokens
.runtime_audit/
__pycache__/
*.pyc
cache files
runtime state
screenshots with secrets
ZIP packages
temporary probes
```
### Pull request checklist
- [ ] Scope is focused.
- [ ] No architecture duplication.
- [ ] No deterministic guard weakened.
- [ ] Source attribution remains correct.
- [ ] Missing/stale data fails closed.
- [ ] Diagnostics are sanitized.
- [ ] API is additive.
- [ ] Static checks pass.
- [ ] Focused tests pass.
- [ ] Futures regression suite ran once.
- [ ] Deployment audit/browser plan is documented.
- [ ] No trade will be executed during verification.
---
## Project Status
### Snapshot
This documentation describes the UI v3 implementation package prepared on 2026-07-21.
Repository base recorded by the implementation package:
```text
3ff79ee0fce31f8d09a7dac357904169d50d9f3e
```
Last known deployed revision before this package:
```text
24d8dad11c0d7316446e9a26b0b074e8630de139
```
The package itself was not committed, pushed, or deployed by the implementation environment.
### Implemented backend/runtime work
- packaged Luxury template is the runtime source;
- overlay installation and SHA-256 manifest;
- runtime status `verified` / `mismatch` / `unknown`;
- no-cache Futures responses;
- KuCoin millisecond range construction;
- conservative DS4 Futures verification;
- DS4/Binance/DS2 normalization and priority;
- per-field provenance and truthful freshness;
- structured source health and merge readiness;
- real market endpoint with four intervals;
- explicit partial/stale/unavailable semantics;
- deterministic state machine and non-executable plan semantics;
- server-side plan/symbol/risk/expiry/readiness/risk revalidation;
- stronger diagnostic redaction;
- read-only runtime audit utility;
- Telegram webhook-only and Linear MCP isolation preserved.
### Implemented UI v3 work
- watchlist and recent markets;
- manual/automatic refresh and density/theme controls;
- keyboard help without execution shortcut;
- Candles/Line chart, volume, crosshair, tooltip, four intervals, three limits;
- market header, source/freshness/readiness, order-book top values;
- display-only diagnostics;
- per-field provenance;
- plan geometry and execution checklist;
- analysis copy/export/history/activity;
- expanded datasource and technical diagnostics;
- responsive desktop/tablet/mobile layout.
### Validation already recorded
Static validation reported:
- modified Python files compiled;
- dashboard JavaScript passed `node --check`;
- DOM ID and static reference checks passed;
- CSS custom-property checks passed;
- whitespace checks passed;
- package ZIP integrity passed.
Behavioral tests, Futures regression tests, authenticated production verification, and deployment were deferred.
### Remaining production work
1. Review documentation and final code diff.
2. Run focused tests and existing Futures regression suite.
3. Verify real DS4 field names and timestamps.
4. Perform one safe KuCoin read-only request.
5. Deploy through the repository/Hugging Face workflow.
6. Run authenticated read-only audit.
7. Inspect Browser Console and Network.
8. Verify real market rendering for all intervals and UI features.
9. Run one BTCUSDT analysis-only request.
10. Confirm Telegram webhook-only mode and Linear MCP isolation.
11. Record commit hash and serving Space revision.
12. Confirm no secret exposure and no trade execution.
---
|