Changelog¶
All notable changes to HermesX are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased] - v2.4.0-dev¶
Release state: these entries describe current-branch changes after the latest released baseline (v2.3.0). They are not stable release commitments until a v2.4.0 release is cut.
Added¶
- Supply-chain artifacts — Dependabot config for Go/npm/GitHub Actions/Docker, CodeQL security analysis, CycloneDX SBOM workflow, and release artifact provenance attestation.
- Egress denied-event audit —
SecureTransportdenied decisions now persist asaudit_logsentries with actionegress.denied;/admin/v1/egress/blocked-logreturns those persisted audit events. - Helm production hardening controls — chart supports existing Secret references for sensitive env vars, configurable ServiceAccount, pod/container security context, read-only root filesystem with
/tmpemptyDir, and optional NetworkPolicy. - Maintainer and security response docs — added CODEOWNERS, MAINTAINERS, and explicit security response targets.
- Admin Usage Aggregation API —
GET /admin/v1/usage?tenant_id=&granularity=daily|monthly&from=&to=endpoint for per-tenant token usage and cost aggregation - K8s Job Sandbox Mode —
SANDBOX_MODE=k8s-jobexecutes tool code via Kubernetes Job API, no privileged containers or DinD required, compatible with GKE Autopilot / EKS Fargate - Pre-built Observability Stack — Grafana dashboard JSON (7 panels), Prometheus alert rules (5), OTel Collector config, one-click deploy via
docker-compose.observability.yml - Redis/MinIO Backup Scripts —
scripts/redis-backup.sh(BGSAVE + S3),scripts/minio-backup.sh(mc mirror),scripts/dr-test.sh(disaster recovery verification) - Eino 0.9 Agent Main Path — native provider model, AgenticMessage blocks, TurnLoop checkpoint resume, and PG/MySQL checkpoint stores;
/v1/agent/chatsupportsinclude_agentic_blocksdebug output
Breaking¶
- SaaS-only product surface — the public entry points are now
hermesx saas-api, HTTP APIs, embedded WebUI, and SaaS Docker/Helm/K8s deployments; former local assistant commands, the gateway runtime, quickstart stack, separate frontend container, and non-SaaS Dockerfiles are no longer supported interfaces - Release artifact consolidation — Release/CI artifacts now build only Linux SaaS service binaries;
Dockerfile.saasis the only published image path, defaults tosaas-api, and bundleswebui/distinto/static - Code execution no longer falls back to host execution —
execute_codereturns an error whenSANDBOX_MODEis unset; production should useSANDBOX_MODE=k8s-job, whilelocalmode requires explicit local SaaS development opt-in outside production
Fixed¶
- API Key Generation Safety —
generateRawKey()changed from panic to returning(string, error);rand.Readfailure now returns HTTP 500 instead of crashing the process - Agent Chat Failure Persistence —
/v1/agent/chatnow persists user/assistant turns only after a successful agent run; runtime and streaming failures no longer leave half-written messages, duplicate resume user turns, or dirty token counters - Agent Chat Same-Session Concurrency — requests for the same
tenant/sessionare serialized at the handler layer to avoid duplicate message, checkpoint, and token writes - Workflow Agent Default Path —
agent_taskdefault executor now usesEinoAgentExecutorinstead of the legacy AIAgent path, sharing theRunConversationTurnLoopSafemain path with the API
Security¶
- BrowserBackend SecretResolver integration —
BrowserBackend.Connect(ctx context.Context, tctx *ToolContext) errornew interface; credentials resolved viaSecretResolverfirst,os.Getenvfallback; all 20 call sites updated;browser_impl.goospackage dependency eliminated - Admin DI injectable safety components —
APIServerConfignow accepts optionalLeakScanner,CanaryDetector, andPolicyStoreinjection points; nil-guarded, backward compatible - HTTP redirect bypass protection (#37) —
agent.go CheckRedirecthook validates redirect target viaegress.ValidateRedirectTarget; rejectsLocationheaders resolving to loopback/private/CGNAT/link-local addresses - RLS FORCE hardening (#27) — migration 109:
execution_receiptsFORCE ROW LEVEL SECURITY; migration 110:egress_rulesENABLE + FORCE RLS+tenant_isolation_egress_rulespolicy (USING + WITH CHECK) - MCP SamplingHandler safety gates (#47) —
NewSamplingHandlerWithSafety(client, interceptor)checks input before and output after LLM calls viaSafetyInterceptor; blocked requests return JSON-RPC error-32000 - Linter compliance (#44) —
osv_check.goinit()OSV_ENDPOINTpublic-endpointos.Getenvannotated with//nolint:forbidigo
Docs¶
- README positioning — reframed HermesX as an Agent-first Runtime Control Plane with audience, pillars, minimal demo, capability matrix, and explicit release-state separation
- Agent-first architecture overview — added
docs/AGENT_FIRST_ARCHITECTURE.mdwith runtime/control-plane/workflow/governance boundaries - Version alignment — aligned README, OpenAPI, and Enterprise Readiness docs around
v2.4.0-devcurrent docs/API baseline andv2.3.0latest released baseline - RBAC role-count consistency — updated docs that still described the older five-role model after platform/security/billing/ops governance roles were added
[2.3.0] - 2026-05-20¶
Latest released baseline referenced by the public README release-state note.
SaaS Cron Scheduler — distributed scheduled task execution engine.
Added¶
- SaaS Cron Scheduler — distributed cron job execution engine built on gocron + Redis distributed locks
internal/scheduler/package:SaasScheduler,syncOnce,execute,execWithTenant- PG poll-sync: every 30s fetches enabled jobs from
cron_jobstable, auto-registers/updates/removes gocron schedules - Idempotent execution:
ON CONFLICT (cron_job_id, scheduled_at) DO NOTHINGprevents duplicate runs - Redis distributed lock:
redislock.WithTries(1)no-retry contention, losing pods skip gracefully - Result delivery:
ResultDelivererinterface pushes execution results back to user's source platform (Telegram/Discord/Slack, etc.) - Lifecycle context: Scheduler holds its own
ctx/cancelFunc; gocron tasks usebaseCtx()for live context at fire time - cron_job_runs table — execution record persistence with
status,duration_ms,result,error,pod_id - RLS write policies (Migration 105) — INSERT/UPDATE/DELETE policies for
cron_job_runsviacurrent_setting('app.current_tenant') - SECURITY DEFINER function (Migration 106) —
scheduler_cleanup_stale_runs()for cross-tenant stale run cleanup
Fixed¶
- Executor RLS bypass — all scheduler writes go through
execWithTenant()which setsSET LOCAL app.current_tenantwithin the transaction, compatible with FORCE RLS - Shutdown ordering —
cronScheduler.Stop()executes beforesyncCancel(), ensuring running tasks drain before context cancellation - gocron task stale context — uses
s.baseCtx()closure instead of sync-time captured context, preventing expired context at fire time - CronJobStore error types —
Get/Update/Deletereturn unifiedstore.ErrNotFoundinstead offmt.Errorf
Changed¶
cleanupStaleRunsrefactored from direct SQL UPDATE to callingscheduler_cleanup_stale_runs($1)SECURITY DEFINER function
[2.2.0] - 2026-05-14¶
Security hardening, bootstrap stabilization, and supply-chain improvements.
Added¶
- IP-level rate limiting for
POST /admin/v1/bootstrap, with matching Nginx limits for WebUI and production load-balancer entrypoints. - Cross-replica bootstrap idempotency via
bootstrap_statein PostgreSQL (ON CONFLICT DO NOTHING+RETURNING idsentinel). - Session titles for SaaS chat sessions, surfaced in the WebUI conversation sidebar.
internal/store/pgunit tests: compile-time interface assertions, bootstrap idempotency logic, and SQL shape validation for scopes (COALESCE) andON CONFLICTidempotency.- OpenAPI spec corrections: title/version/contact updated to HermesX v2.2.0; 11 missing routes added (
/health/live,/health/ready,/metrics,/v1/agent/chat,/v1/gdpr/cleanup-minio, all/admin/v1/*endpoints); paths now accurate at 33+ documented routes.
Fixed¶
- PostgreSQL API key persistence now writes and reads
scopes, allowing admin API keys to satisfyRequireScope("admin"). - Release workflow now builds with Go 1.25 and generates checksums for
hermesx-*artifacts. - Documentation now reflects the actual React WebUI stack and v2.2.0 baseline.
- WebUI security headers (CSP, HSTS, X-Frame-Options), URL encoding, auth retry on 401, and N+1 query eliminated in session list.
Changed¶
HasScopecompatibility policy documented: emptyScopes= legacy key granted non-admin access;adminscope always requires explicit grant. New keys carry explicit scopes.- Memory
Curator.deduplicateEntries: Phase 1 now O(n) exact-key dedup via map; Phase 2 content-similarity scan limited to key-unique set (m ≤ n), resolving O(n²) worst case atMaxMemories > 100.
Security¶
- GitHub Actions supply-chain hardening:
actions/checkout,actions/setup-go, andsoftprops/action-gh-releaseall pinned to full commit SHA. - Bootstrap endpoint now enforces 5 RPM IP rate limit at application layer, Nginx WebUI layer, and production LB layer.
[2.0.0] - 2026-05-08¶
Major release: complete rebrand from Hermes to HermesX, combined with enterprise hardening Phase 1.
Added¶
- ExecutionReceipt API: auditable tool invocation records with idempotency deduplication and trace correlation
- execution receipts are created by the internal tool execution path via
DispatchWithReceipt() GET /v1/execution-receipts— list with pagination and filters (auditor role)GET /v1/execution-receipts/{id}— get by ID (auditor role)- Prometheus business metrics: 11+ custom metrics covering HTTP requests, LLM completions, tool executions, rate limiting, and store operations
- MiniMaxi Anthropic API mode: Anthropic API-compatible mode via MiniMaxi provider, including stress test validation
auditorRBAC role: read-only access to audit logs and execution receipts- Full OpenAPI specification: 22 documented endpoints with schemas, tags, and security schemes, available at
GET /v1/openapi - Production Docker compose:
docker-compose.prod.ymlwith PostgreSQL 16, Redis 7 (AOF + LRU), MinIO, OTel Collector, and Jaeger - Enterprise demo script: 11-step
./examples/enterprise-saas-demo/demo.shwalkthrough - Backup/restore scripts:
scripts/backup/backup.sh(pg_dump + gzip, 7-day retention) andscripts/backup/restore.sh(single-transaction restore)
Changed¶
- Project name: Hermes → HermesX — independent enterprise agent platform
- Binary name:
hermes→hermesx - Entry point:
cmd/hermes/→cmd/hermesx/ - GitHub repository:
https://github.com/Colin4k1024/hermesx.git - All internal references: package imports, variable names, comments, log messages, and environment variables updated from
hermes/HERMEStohermesx/HERMESX - Configuration files:
docker-compose.yml,.env.example, and CI workflow files updated - Documentation: all docs reflect HermesX branding and v2.0.0 version
Fixed¶
- CI RLS pool URL replacement: corrected credential substitution for
hermesx_testin CI environment (was failing lint and integration tests) - API key tenant boundary: tenant derivation is now strictly from credential context; body-supplied
tenant_idonly honored for admin role callers generateRawKey()hardening: explicit panic oncrypto/rand.Readfailure (previously silently returned partial key)
Refactored¶
- Complete codebase rebrand: hermes → hermesx across all source files, test files, configs, and scripts
Docs¶
- ARCHITECTURE.md: system architecture overview with component diagram and data flows
- SECURITY_MODEL.md: threat model, authentication chain, RLS, and sandbox isolation
- RBAC_MATRIX.md: 5 roles × 10 resources permission matrix
- ENTERPRISE_READINESS.md: Phase 1 enterprise readiness assessment — 12 capability areas with evidence
- STRESS_TEST_REPORT.md: MiniMaxi Anthropic API mode stress test results
- Expanded DEPLOYMENT.md: environment variable reference, Prometheus metrics table, backup/restore procedures, horizontal scaling guidelines, security hardening checklist, and rollback strategy