N0: rename Hermes → Nomos (standalone commit)

Problem: "Hermes" collides with Nous Researchs unrelated product;
  unclear identity for the resident agent.

  Change: Rename the live service identity across 39 files:
  - cmd/hermes/ → cmd/nomos/ (binary, env vars NOMOS_*)
  - internal/config/ server.go (NomosAgentSlug, nomosAgentID)
  - compose/hermes/ → compose/nomos/ (Dockerfile, service name)
  - hermes/ → nomos/ (SOUL.md, config.yaml, skills/)
  - .agents/HERMES.md → NOMOS.md (persona)
  - tools/setup-hermes-soul.sh → setup-nomos-soul.sh
  - seeds/inventory.yaml (agent:hermes → agent:nomos)
  - migrations/014_rename_agent_hermes_to_nomos.up.sql
  - Caddy vhost hermes.hubris.network → nomos.hubris.network
  - All referencing docs, scripts, ADR notes

  History preserved: archive/, plans/done/, ADRs not rewritten.
  Matrix @hermes notifier account and Legacy bin/hermes on LXC 129
  intentionally untouched (out of scope).

  Risk: N0 is identity-only rename; zero behavioral changes.
  Verification: go build ./... passes; docker compose --profile full
  resolves nomos service; grep -ri hermes (excluding archive/plans)
  returns only intentional refs (LLM model name, Matrix user).
This commit is contained in:
2026-07-08 14:14:56 +02:00
parent 9d9cbb63c4
commit 2b3aa248b1
39 changed files with 230 additions and 200 deletions

View File

@@ -20,7 +20,7 @@ type Config struct {
// Auth (Phase 2: static bearer tokens + OIDC JWT)
APIToken string // operator/CI bearer token for the REST API
MCPBearerToken string // shared secret for Hermes→API MCP calls
MCPBearerToken string // shared secret for Nomos→API MCP calls
OIDCIssuer string // OIDC issuer URL for JWT validation (e.g. https://authentik.example.com/application/o/oikos/)
OIDCClientID string // OIDC client ID (aud claim expected in JWT)
@@ -54,9 +54,9 @@ type Config struct {
// Approval HMAC secret (Phase 3)
ApprovalHMACSecret string
// Hermes agent entity ID (Phase 4)
HermesAgentID string
HermesAgentSlug string
// Nomos agent entity ID (Phase 4)
NomosAgentID string
NomosAgentSlug string
// Infisical (Phase 5)
InfisicalSiteURL string
@@ -151,11 +151,11 @@ func FromEnv() Config {
if v := os.Getenv("OIKOS_APPROVAL_HMAC_SECRET"); v != "" {
c.ApprovalHMACSecret = v
}
if v := os.Getenv("OIKOS_HERMES_AGENT_ID"); v != "" {
c.HermesAgentID = v
if v := os.Getenv("OIKOS_NOMOS_AGENT_ID"); v != "" {
c.NomosAgentID = v
}
if v := os.Getenv("OIKOS_HERMES_AGENT_SLUG"); v != "" {
c.HermesAgentSlug = v
if v := os.Getenv("OIKOS_NOMOS_AGENT_SLUG"); v != "" {
c.NomosAgentSlug = v
}
// Phase 5: Infisical secrets

View File

@@ -137,16 +137,16 @@ func NewHandler(ctx context.Context, pool *db.Pool, cfg config.Config) http.Hand
r.With(combinedAuth(cfg)).Get("/api/v1/events/stream", s.serveSSE)
// Mount MCP at /mcp (plan R3-10)
hermesAgentID := uuid.Nil
if cfg.HermesAgentID != "" {
if id, err := uuid.Parse(cfg.HermesAgentID); err == nil {
hermesAgentID = id
nomosAgentID := uuid.Nil
if cfg.NomosAgentID != "" {
if id, err := uuid.Parse(cfg.NomosAgentID); err == nil {
nomosAgentID = id
}
}
if hermesAgentID == uuid.Nil && cfg.HermesAgentSlug != "" {
_ = pool.QueryRow(ctx, "SELECT id FROM entities WHERE slug = $1", cfg.HermesAgentSlug).Scan(&hermesAgentID)
if nomosAgentID == uuid.Nil && cfg.NomosAgentSlug != "" {
_ = pool.QueryRow(ctx, "SELECT id FROM entities WHERE slug = $1", cfg.NomosAgentSlug).Scan(&nomosAgentID)
}
r.With(combinedAuth(cfg)).Handle("/mcp", mcphandler.NewHandler(pool, cfg.MCPBearerToken, hermesAgentID))
r.With(combinedAuth(cfg)).Handle("/mcp", mcphandler.NewHandler(pool, cfg.MCPBearerToken, nomosAgentID))
return r
}

View File

@@ -37,7 +37,7 @@ func objSchema(props ...prop) *jsonschema.Schema {
}
// NewHandler creates an http.Handler that serves the Oikos MCP server.
// agentID is the Hermes agent entity UUID; tool calls are logged to agent_activity.
// agentID is the Nomos agent entity UUID; tool calls are logged to agent_activity.
func NewHandler(pool *db.Pool, token string, agentID uuid.UUID) http.Handler {
s := newServer(pool, agentID)
handler := mcp.NewStreamableHTTPHandler(func(r *http.Request) *mcp.Server {
@@ -258,7 +258,7 @@ func newServer(pool *db.Pool, agentID uuid.UUID) *mcp.Server {
nStr(args["status"])), nil
})
register(&mcp.Tool{Name: "request_execution", Description: "Request a gated execution (Hermes-only mutation path). Supported actions: restart, systemctl, pct_exec, apt_upgrade.",
register(&mcp.Tool{Name: "request_execution", Description: "Request a gated execution (agent-only mutation path). Supported actions: restart, systemctl, pct_exec, apt_upgrade.",
InputSchema: objSchema(
prop{"target", "string", "Target entity slug (e.g. lxc:caddy)"},
prop{"action", "string", "Action: restart, systemctl, pct_exec, apt_upgrade"},