Spaces:
Sleeping
Sleeping
File size: 3,072 Bytes
2e658e7 | 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 | #!/usr/bin/env python3
"""Fail-closed preflight for the immutable Hermes upstream integration.
The overlay still uses a small number of source-shape patches because upstream
has no supported extension hook for these integration points. This verifier is
run during the image build *before* dependency installation. A changed upstream
shape therefore fails the build explicitly instead of producing a partially
mounted application at runtime.
"""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
class IntegrationShapeError(RuntimeError):
pass
def _read(path: Path) -> str:
if not path.is_file():
raise IntegrationShapeError(f"required upstream file missing: {path}")
return path.read_text(encoding="utf-8")
def _require_one_of(text: str, variants: tuple[str, ...], label: str) -> None:
if not any(variant in text for variant in variants):
raise IntegrationShapeError(f"upstream integration marker missing: {label}")
def verify(root: Path) -> list[str]:
root = root.resolve()
checks: list[str] = []
for name in ("package-lock.json", "uv.lock"):
path = root / name
if not path.is_file():
raise IntegrationShapeError(f"required deterministic lockfile missing: {path}")
checks.append(name)
web_server = _read(root / "hermes_cli" / "web_server.py")
_require_one_of(
web_server,
(
'app = FastAPI(title="Hermes Agent", version=__version__, lifespan=_lifespan)',
"from tools.futures_dashboard_api import router as _futures_dashboard_router",
),
"FastAPI application mount",
)
_require_one_of(
web_server,
(
r'allow_origin_regex=r"^https?://(localhost|127\.0\.0\.1)(:\d+)?$"',
r"https://[A-Za-z0-9-]+\.hf\.space",
),
"CORS source shape",
)
_require_one_of(
web_server,
('@app.get("/api/status")', '@app.get("/health")'),
"health/status route",
)
checks.append("hermes_cli/web_server.py")
toolsets = _read(root / "toolsets.py")
_require_one_of(toolsets, ("TOOLSETS = {\n", '"futures_trading"'), "toolsets registry")
checks.append("toolsets.py")
public_paths = _read(root / "hermes_cli" / "dashboard_auth" / "public_paths.py")
_require_one_of(
public_paths,
(' "/api/cron/fire",\n', '"/api/telegram/webhook"'),
"dashboard public paths",
)
checks.append("hermes_cli/dashboard_auth/public_paths.py")
return checks
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument("root", nargs="?", default="/opt/hermes")
args = parser.parse_args(argv)
try:
checks = verify(Path(args.root))
except (OSError, UnicodeError, IntegrationShapeError) as exc:
print(f"ERROR: {exc}", file=sys.stderr)
return 1
print(f"upstream_integration_preflight=PASS checks={len(checks)}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
|