Commit Graph

78 Commits

Author SHA1 Message Date
AdrianoDev daa4e02971 feat(V2): migrazione deribit (client, leverage_cap, tools)
Task 6.1 V2.0.0: copia client.py + leverage_cap.py da services/mcp-deribit
con import riscritti (mcp_common -> cerbero_mcp.common, mcp_deribit ->
cerbero_mcp.exchanges.deribit). Estratte 34 tool async (28 endpoint +
is_testnet/environment_info + helpers) in tools.py: pure logica senza
FastAPI/ACL. Audit calls per ora rimossi (TODO: cabling via router su
request.state.environment).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 18:23:44 +02:00
AdrianoDev 2a268b3a33 feat(V2): build_app con swagger /apidocs + middleware + handlers
Aggiunge /docs e /redoc alla whitelist auth (path disabilitati, nessun rischio sicurezza).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 18:20:17 +02:00
AdrianoDev 73f880e7f2 feat(V2): ClientRegistry lazy con lock per chiave
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 18:18:18 +02:00
AdrianoDev 80a4a88cb1 feat(V2): error envelope module estratto da server.py 2026-04-30 18:17:15 +02:00
AdrianoDev 993326136b test(V2): migrazione test common/
Copiati e aggiornati i test da services/common/tests/ a tests/unit/common/.
Import aggiornati da mcp_common a cerbero_mcp.common. Eliminati test di
funzionalità V1-only (app_factory, environment, auth/Principal, server_base).
Refactored test_audit.py (principal→actor str) e test_mcp_bridge.py
(TokenStore→valid_tokens set). 71/71 test passano.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 18:16:26 +02:00
AdrianoDev 1a1f9c43ba refactor(V2): audit.py usa actor:str invece di Principal, rimuovi legacy common/auth.py
- Eliminato src/cerbero_mcp/common/auth.py (V1 Principal/TokenStore/ACL)
- audit_write_op: parametro principal:Principal → actor:str|None
- mcp_bridge.py: TokenStore → valid_tokens:set[str] (V2 bearer model)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 18:14:10 +02:00
AdrianoDev 3868ba60ce feat(V2): migrazione common/ (indicators, options, microstructure, stats, http, audit, logging, mcp_bridge + auth) 2026-04-30 18:12:11 +02:00
AdrianoDev 04a34fc179 fix(V2): hoist fastapi Request import, ripristina importlib mode 2026-04-30 18:10:41 +02:00
AdrianoDev 2934a2d26a feat(V2): bearer auth middleware con compare_digest
Implementa install_auth_middleware con whitelist /health /apidocs /openapi.json,
token timing-safe via secrets.compare_digest, request.state.environment injection.
Fix pyproject: --import-mode=prepend (importlib + PEP563 rompe FastAPI Request injection).
Rimosso from __future__ import annotations da test_auth.py per stesso motivo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 18:09:21 +02:00
AdrianoDev 97d93a5139 feat(V2): pydantic settings con secret str + test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 18:04:40 +02:00
AdrianoDev 005300205b chore(V2): .env.example consolidato, .env gitignored 2026-04-30 18:03:22 +02:00
AdrianoDev 8df64b5176 chore(V2): scheletro src/cerbero_mcp + tests/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 18:02:22 +02:00
AdrianoDev 8fd182e295 chore(V2): pyproject singolo package cerbero-mcp, rimosso workspace
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 18:01:16 +02:00
AdrianoDev b8753afad2 docs(plan): V2.0.0 implementation plan task-by-task
Plan a 12 phase per implementare V2.0.0:
- Phase 0: bootstrap struttura nuova
- Phase 1: settings + .env consolidato
- Phase 2: auth bearer middleware
- Phase 3: migrazione common/
- Phase 4: client_registry lazy
- Phase 5: build_app + swagger /apidocs
- Phase 6: migrazione 6 exchange (deribit template + 5 ripetizioni)
- Phase 7: __main__ entrypoint con lifespan
- Phase 8: integration test env routing
- Phase 9: Dockerfile + docker-compose minimo
- Phase 10: pulizia V1 (services/, gateway/, secrets/, docker/)
- Phase 11: README riscritto, DEPLOYMENT eliminato
- Phase 12: quality gate finale

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 17:58:13 +02:00
AdrianoDev 9a137563e8 docs(spec): V2.0.0 unified image + token-based env routing
Spec architetturale per V2.0.0: collassa 7 immagini Docker (gateway Caddy
+ 6 servizi MCP) in una singola immagine multi-router. Switch
testnet/mainnet diventa runtime per-request via bearer token (TESTNET_TOKEN
/ MAINNET_TOKEN). Configurazione consolidata in singolo .env, secret JSON
eliminati. Swagger UI esposto a /apidocs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 17:45:26 +02:00
AdrianoDev 7fa269de14 feat(deploy): auto-include docker-compose.local.yml override
Lo script deploy-noclone.sh ora carica automaticamente come ultimo -f
un eventuale $DEPLOY_DIR/docker-compose.local.yml se esiste. Utile per
fix specifici macchina (es. DOCKER_API_VERSION watchtower su daemon
vecchi). Gitignored per design — non versionato nel repo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 22:44:01 +02:00
AdrianoDev c9ab211c38 chore(build-push): riusa docker login persistente
Skip login se ~/.docker/config.json contiene già auth per il registry.
Permette di fare 'docker login' una volta e poi lanciare lo script
senza dover esportare GITEA_PAT ad ogni run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:40:56 +02:00
AdrianoDev 287c4b5372 chore: rimuovi deploy.sh e cache registry buildx
- scripts/deploy.sh eliminato (sostituito da deploy-noclone.sh)
- build-push.sh: rimossa cache-from/cache-to registry (cache buildx
  locale del laptop sufficiente, niente più image buildcache:* sul
  registry Gitea)
- doc cleanup riferimenti orfani

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:25:38 +02:00
AdrianoDev ba29572e93 chore(deploy): build locale + deploy no-clone, rimuovi CI Gitea
- scripts/build-push.sh: replica job CI in locale (8 image, cache buildx, tag :latest + :sha-X)
- scripts/deploy-noclone.sh: deploy VPS senza clone (curl raw config + image pull)
- rimossa .gitea/workflows/ci.yml
- README + DEPLOYMENT aggiornati: laptop -> registry -> VPS, paths /docker/cerbero_mcp
- ruff fix su 3 test (I001, SIM117, UP037, F821)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 20:37:06 +02:00
AdrianoDev 4f3e959805 feat(deploy): docker-compose.traefik.yml overlay per behind-Traefik
ci / ruff lint (push) Failing after 13s
ci / mypy mcp_common (push) Successful in 22s
ci / pytest (push) Successful in 32s
ci / validate compose + Caddyfile (push) Failing after 2m23s
ci / build & push to registry (push) Has been skipped
Per VPS condiviso (es. con Gitea) dove Traefik gestisce già 80/443.

- gateway/Caddyfile: env-aware listen + auto_https + trusted_proxies
  (defaults invariati per modalità standalone).
- docker-compose.traefik.yml: overlay che rimuove ports binding host,
  attacca gateway alla network esterna di Traefik, set labels per
  routing Host(cerbero-mcp.tielogic.xyz) + TLS via certresolver
  Traefik. Caddy ascolta plain HTTP :80 interno.
- scripts/deploy.sh: rileva BEHIND_TRAEFIK=true → aggiunge -f
  docker-compose.traefik.yml a tutti i docker compose call.
- DEPLOYMENT.md: nuova sezione 2a (topologia standalone vs behind-traefik)
  + sotto-sezione modalità behind-Traefik con env vars richieste.

Uso:
  docker compose -f docker-compose.prod.yml -f docker-compose.traefik.yml \
                 --env-file .env up -d

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 09:56:07 +02:00
AdrianoDev a1110c8ecb feat(safety+audit+deploy): consistency_check + audit log file sink + deploy script
ci / ruff lint (push) Failing after 12s
ci / mypy mcp_common (push) Successful in 25s
ci / pytest (push) Successful in 35s
ci / validate compose + Caddyfile (push) Successful in 2m3s
ci / build & push to registry (push) Has been skipped
#2 Env switch safety:
- mcp_common/environment.py: nuova consistency_check() che previene
  switch accidentali a mainnet. Solleva EnvironmentMismatchError se
  resolved=mainnet senza creds["environment"]="mainnet" esplicito,
  o se declared/resolved mismatch. Override via STRICT_MAINNET=false.
- Wirato in app_factory.run_exchange_main al boot.
- 6 nuovi test consistency.

#3 Audit log persistence:
- mcp_common/audit.py: TimedRotatingFileHandler aggiuntivo se env
  AUDIT_LOG_FILE settato. Rotation midnight UTC, retention 30gg
  default (AUDIT_LOG_BACKUP_DAYS). Format JSONL con SecretsFilter.
- docker-compose.prod.yml: bind mount /var/log/cerbero-mcp + env
  AUDIT_LOG_FILE per i 4 servizi exchange (write endpoints).
- 2 nuovi test file sink.

#1 Deploy script:
- scripts/deploy.sh: idempotente, fa docker login + clone/pull repo +
  copia secrets chmod 600 + crea .env + setup audit dir + pull image
  + up + smoke test pubblico HTTPS.
- DEPLOYMENT.md aggiornato: sezioni 2 (script), 3 (safety mainnet),
  4 (audit log query), renumber sezioni successive.

Test: 488/488 verdi.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 09:29:04 +02:00
AdrianoDev 019b7e3298 docs: README + DEPLOYMENT con stato CI/CD funzionante
ci / ruff lint (push) Successful in 14s
ci / mypy mcp_common (push) Successful in 23s
ci / pytest (push) Successful in 30s
ci / validate compose + Caddyfile (push) Successful in 2m2s
ci / build & push to registry (push) Successful in 1m32s
README aggiunge sezione 'CI/CD pipeline' che descrive i 5 job e i tag
image. DEPLOYMENT espande sez. 1 con dettagli runner Gitea (network
gitea_gitea-internal, image runner-images, label ubuntu-latest) e
configurazione secret user-level REGISTRY_TOKEN con scope write:package.
2026-04-29 09:18:30 +02:00
AdrianoDev 2fb7043790 ci: push base image al registry + parametrizza BASE_IMAGE nei service Dockerfile
ci / ruff lint (push) Successful in 13s
ci / mypy mcp_common (push) Successful in 23s
ci / pytest (push) Successful in 29s
ci / validate compose + Caddyfile (push) Successful in 2m0s
ci / build & push to registry (push) Successful in 1m43s
Buildx con driver docker-container non vede image caricate nel daemon
locale. Soluzione: push base come git.tielogic.xyz/adriano/cerbero-mcp/
base:latest e i 6 service Dockerfile usano ${BASE_IMAGE}:${BASE_TAG}
con default "cerbero-base" per dev locale, override CI a path registry.
2026-04-29 09:09:47 +02:00
AdrianoDev 38fd7db259 ci: usa secrets.REGISTRY_TOKEN per docker login (scope write:package)
ci / ruff lint (push) Successful in 14s
ci / mypy mcp_common (push) Successful in 26s
ci / pytest (push) Successful in 32s
ci / validate compose + Caddyfile (push) Successful in 2m24s
ci / build & push to registry (push) Failing after 4m13s
GITEA_TOKEN auto-iniettato non include write:package scope necessario per
push al registry. Serve PAT manuale creato in User Settings → Applications
con scope write:package, salvato come secret repo REGISTRY_TOKEN.
2026-04-29 08:53:31 +02:00
AdrianoDev 9da2e12473 lint: ruff clean services/ (autofix + manual + ignore E741)
ci / ruff lint (push) Successful in 15s
ci / validate compose + Caddyfile (push) Successful in 2m6s
ci / mypy mcp_common (push) Successful in 30s
ci / pytest (push) Successful in 34s
ci / build & push to registry (push) Failing after 47s
- 24 autofix safe (SIM105 contextlib.suppress, F401 unused imports,
  I001 import order, B007 unused loop var, F811 redef, F841 unused).
- 15 unsafe-fix (UP038 X|Y in isinstance, SIM108 ternary, ecc.).
- Manual fix: SIM102 nested if in deribit term_structure, E402 imports
  in test_cot.py + sentiment server.py.
- Ignore E741 (variabili 'l' in list comprehensions deribit/client.py
  — stilistico, non bug).

Tests: 478/478 verdi.
2026-04-29 08:44:12 +02:00
AdrianoDev 910f80c99b ci: setup-python@v5 con 3.13 + curl uv install (setup-uv@v5 non applicava python-version)
ci / mypy mcp_common (push) Successful in 25s
ci / pytest (push) Successful in 33s
ci / validate compose + Caddyfile (push) Successful in 3m35s
ci / build & push to registry (push) Has been skipped
ci / ruff lint (push) Failing after 52s
2026-04-29 08:29:24 +02:00
AdrianoDev fe7a9dd9c0 ci: usa astral-sh/setup-uv@v5 con python-version 3.13 (gestisce uv + Python + cache)
ci / ruff lint (push) Failing after 55s
ci / mypy mcp_common (push) Successful in 24s
ci / pytest (push) Successful in 30s
ci / build & push to registry (push) Has been cancelled
ci / validate compose + Caddyfile (push) Has been cancelled
2026-04-29 08:23:50 +02:00
AdrianoDev 503f7a4b17 ci: install Python 3.13 via uv (runner image ha solo 3.10)
ci / ruff lint (push) Failing after 21s
ci / mypy mcp_common (push) Successful in 32s
ci / pytest (push) Successful in 39s
ci / build & push to registry (push) Has been cancelled
ci / validate compose + Caddyfile (push) Has been cancelled
2026-04-29 08:22:29 +02:00
AdrianoDev 0956283463 ci: runs-on ubuntu-latest (label più stabile)
ci / ruff lint (push) Failing after 37s
ci / mypy mcp_common (push) Successful in 20s
ci / pytest (push) Successful in 30s
ci / validate compose + Caddyfile (push) Failing after 3m40s
ci / build & push to registry (push) Has been cancelled
2026-04-29 08:21:07 +02:00
AdrianoDev 7cc28cd6de ci: install uv via astral script + add to GITHUB_PATH
ci / ruff lint (push) Failing after 6s
ci / mypy mcp_common (push) Failing after 7s
ci / pytest (push) Failing after 6s
ci / validate compose + Caddyfile (push) Failing after 2m27s
ci / build & push to registry (push) Has been cancelled
2026-04-29 08:18:07 +02:00
AdrianoDev b91f843d89 ci: remove probe workflow (runner network issue resolved)
ci / ruff lint (push) Failing after 1m4s
ci / mypy mcp_common (push) Failing after 13s
ci / pytest (push) Failing after 13s
ci / build & push to registry (push) Has been cancelled
ci / validate compose + Caddyfile (push) Has been cancelled
2026-04-29 08:13:50 +02:00
AdrianoDev fd811d0692 ci(probe): minimal workflow per diagnosticare runner shell/tools
ci / ruff lint (push) Failing after 31s
ci / mypy mcp_common (push) Failing after 37s
ci / pytest (push) Failing after 31s
ci / validate compose + Caddyfile (push) Failing after 31s
probe / probe shell + tools (push) Successful in 1s
ci / build & push to registry (push) Has been skipped
2026-04-29 07:58:50 +02:00
AdrianoDev 1fea7d4ea1 ci: install uv via pipx (setup-uv@v3 era skipped da Gitea runner)
ci / ruff lint (push) Failing after 42s
ci / mypy mcp_common (push) Failing after 41s
ci / pytest (push) Failing after 35s
ci / validate compose + Caddyfile (push) Failing after 44s
ci / build & push to registry (push) Has been skipped
2026-04-29 07:54:17 +02:00
AdrianoDev b1aea194ad docs: add COT report tools to README macro section
ci / ruff lint (push) Failing after 39s
ci / mypy mcp_common (push) Failing after 27s
ci / pytest (push) Failing after 33s
ci / validate compose + Caddyfile (push) Failing after 37s
ci / build & push to registry (push) Has been skipped
2026-04-29 00:10:06 +02:00
AdrianoDev 8dfb932c8c feat(mcp-macro): expose COT report tools via MCP endpoint 2026-04-29 00:09:20 +02:00
AdrianoDev dc285daac8 feat(mcp-macro): fetch_cot_extreme_positioning scanner
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 00:06:52 +02:00
AdrianoDev 2474445b4c feat(mcp-macro): fetch_cot_disaggregated async fetcher with cache 2026-04-29 00:03:53 +02:00
AdrianoDev 66bcab05f9 feat(mcp-macro): fetch_cot_tff async fetcher with cache 2026-04-29 00:02:06 +02:00
AdrianoDev e206df49e4 feat(mcp-macro): add parse_tff_row + parse_disagg_row Socrata mappers 2026-04-29 00:00:04 +02:00
AdrianoDev bf152d90fd feat(mcp-macro): add compute_percentile + classify_extreme pure helpers 2026-04-28 23:58:38 +02:00
AdrianoDev 201f263c77 feat(mcp-macro): add CFTC contract codes constants for COT report 2026-04-28 23:57:31 +02:00
AdrianoDev 28e77cddee docs(plan): COT report implementation plan (8 tasks TDD)
ci / ruff lint (push) Failing after 33s
ci / mypy mcp_common (push) Failing after 31s
ci / pytest (push) Failing after 43s
ci / validate compose + Caddyfile (push) Failing after 38s
ci / build & push to registry (push) Has been skipped
2026-04-28 23:54:05 +02:00
AdrianoDev ad3f542c0f docs: fix markdown lint COT spec (blanks, table padding, code lang)
ci / ruff lint (push) Failing after 38s
ci / mypy mcp_common (push) Failing after 36s
ci / pytest (push) Failing after 34s
ci / validate compose + Caddyfile (push) Failing after 32s
ci / build & push to registry (push) Has been skipped
2026-04-28 23:51:01 +02:00
AdrianoDev b218ac3a2c docs: spec design COT report per mcp-macro
ci / mypy mcp_common (push) Failing after 33s
ci / ruff lint (push) Failing after 37s
ci / pytest (push) Failing after 28s
ci / validate compose + Caddyfile (push) Failing after 33s
ci / build & push to registry (push) Has been skipped
TFF (gpe5-46if) per equity/financial: ES, NQ, RTY, ZN, ZB, 6E, 6J, DX
Disaggregated (72hh-3qpy) per commodities: CL, GC, SI, HG, ZW, ZC, ZS

3 tool MCP: get_cot_tff, get_cot_disaggregated,
get_cot_extreme_positioning (scanner percentile 5/95).

Pure-logic helper + httpx integration test + ACL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 23:43:40 +02:00
AdrianoDev c31ee0a121 ci: usa astral-sh/setup-uv@v3 (cache integrato, no curl|sh fragile)
ci / ruff lint (push) Failing after 55s
ci / pytest (push) Failing after 32s
ci / validate compose + Caddyfile (push) Failing after 32s
ci / build & push to registry (push) Has been skipped
ci / mypy mcp_common (push) Failing after 31s
2026-04-28 23:39:17 +02:00
AdrianoDev a2fdca3afd ci: clean runs-on syntax (runner stabile post crash-loop fix)
ci / ruff lint (push) Failing after 42s
ci / mypy mcp_common (push) Failing after 27s
ci / pytest (push) Failing after 32s
ci / validate compose + Caddyfile (push) Failing after 30s
ci / build & push to registry (push) Has been skipped
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 23:24:33 +02:00
AdrianoDev eec1c11cb3 ci: try array syntax runs-on
ci / ruff lint (push) Failing after 29s
ci / mypy mcp_common (push) Failing after 27s
ci / pytest (push) Failing after 29s
ci / validate compose + Caddyfile (push) Failing after 34s
ci / build & push to registry (push) Has been skipped
2026-04-28 23:23:51 +02:00
AdrianoDev 05b431c9c1 ci: try ubuntu-22.04 label
ci / ruff lint (push) Failing after 40s
ci / pytest (push) Failing after 33s
ci / mypy mcp_common (push) Failing after 29s
ci / validate compose + Caddyfile (push) Failing after 34s
ci / build & push to registry (push) Has been skipped
2026-04-28 23:19:59 +02:00
AdrianoDev 59ae9687c8 ci: runs-on tielogic-ci (label specifica del runner registrato)
ci / ruff lint (push) Failing after 1m11s
ci / mypy mcp_common (push) Failing after 26s
ci / pytest (push) Failing after 36s
ci / validate compose + Caddyfile (push) Failing after 1m56s
ci / build & push to registry (push) Has been cancelled
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 23:17:43 +02:00
AdrianoDev 65641a7de8 ci: validate-config job + cache registry-based
ci / ruff lint (push) Has been cancelled
ci / mypy mcp_common (push) Has been cancelled
ci / pytest (push) Has been cancelled
ci / validate compose + Caddyfile (push) Has been cancelled
ci / build & push to registry (push) Has been cancelled
- Nuovo job validate-config: docker compose -f docker-compose.{yml,prod.yml}
  config -q (verifica sintassi YAML + variabili env) + caddy validate
  --config Caddyfile (sintassi gateway).
- build-and-push ora needs anche validate-config: niente push image se
  compose o Caddyfile sono rotti.
- Cache Docker buildx passata da type=gha (richiede backend cache server
  Gitea Actions configurato) a type=registry,ref=<prefix>/buildcache:<name>
  che usa il registry stesso come storage cache. Funziona out-of-the-box,
  niente setup extra.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 23:02:17 +02:00