{"openapi":"3.0.3","info":{"title":"Memory Remediation Approval Gateway","description":"Human-in-the-loop approval gateway for AI-generated memory remediation recommendations.\n\nThis service validates HMAC tokens from email links, displays recommendation details with\nevidence and risk scores, allows users to approve or reject memory limit changes, and\nmaintains a complete audit trail of all decisions.\n\nWhen a recommendation is approved, the service modifies `deploy.resources.limits.memory`\nin the service's docker-compose.yml and restarts the container using `docker compose up -d`.\n\n## Token Security\n\nAll recommendation tokens are HMAC-SHA256 signed and expire 24 hours after generation.\nTokens can only be used once and are rate-limited (1 approval per container per hour).\n","version":"1.0.0","contact":{"name":"Haiven Infrastructure"}},"servers":[{"url":"http://remediation-approval:8050","description":"Internal Docker network"},{"url":"https://remediation.haiven.site","description":"Traefik (internal)"},{"url":"https://remediation.haiven.site","description":"Traefik (external)"}],"tags":[{"name":"Health","description":"Service health and status"},{"name":"Recommendations","description":"View and manage memory remediation recommendations"},{"name":"Audit","description":"Approval and rejection history"}],"paths":{"/health":{"get":{"tags":["Health"],"summary":"Health check","description":"Returns service health status.","operationId":"healthCheck","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/pending":{"get":{"tags":["Recommendations"],"summary":"List pending recommendations","description":"Lists all unapproved and unrejected memory remediation recommendations.\nDisplays container name, recommended action, new memory limit, risk score,\ncreation timestamp, and expiration status.\n","operationId":"listPending","responses":{"200":{"description":"HTML page with pending recommendations","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/details/{token}":{"get":{"tags":["Recommendations"],"summary":"View recommendation details","description":"Shows full evidence, LLM analysis, and metrics for a recommendation.\nIncludes current memory usage, 24h trends, risk score, LLM analysis,\nand compose file path. Displays Approve/Reject buttons if token is valid.\n","operationId":"getDetails","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"HMAC-SHA256 approval token (hex string)"}],"responses":{"200":{"description":"HTML page with recommendation details","content":{"text/html":{"schema":{"type":"string"}}}},"403":{"description":"Invalid token signature"},"404":{"description":"Token not found or already consumed"},"410":{"description":"Token expired (>24h old)"}}}},"/approve/{token}":{"get":{"tags":["Recommendations"],"summary":"Show approval confirmation","description":"Displays a confirmation page before applying the memory change.\nShows before/after comparison, risk score, and restart warning.\n","operationId":"approveView","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"HMAC-SHA256 approval token (hex string)"}],"responses":{"200":{"description":"HTML confirmation page","content":{"text/html":{"schema":{"type":"string"}}}},"403":{"description":"Invalid token signature"},"404":{"description":"Token not found"},"410":{"description":"Token expired"}}}},"/approve/{token}/confirm":{"post":{"tags":["Recommendations"],"summary":"Apply approved memory change","description":"Executes the approved memory remediation:\n1. Validates token integrity and expiration\n2. Checks rate limit (max 1 approval per hour per container)\n3. Modifies `deploy.resources.limits.memory` in docker-compose.yml\n4. Runs `docker compose up -d` to restart the container\n5. Records the action in the audit log\n","operationId":"approveConfirm","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"HMAC-SHA256 approval token (hex string)"}],"responses":{"200":{"description":"HTML success page with change summary","content":{"text/html":{"schema":{"type":"string"}}}},"403":{"description":"Invalid token signature"},"404":{"description":"Token or compose file not found"},"410":{"description":"Token expired"},"429":{"description":"Rate limited (approved within last hour)"},"500":{"description":"Compose modification or restart failed"}}}},"/reject/{token}":{"get":{"tags":["Recommendations"],"summary":"Reject recommendation","description":"Marks a recommendation as rejected. No changes are made to compose files\nor containers. Decision is recorded in the audit log.\n","operationId":"rejectRecommendation","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"HMAC-SHA256 approval token (hex string)"}],"responses":{"200":{"description":"HTML confirmation page","content":{"text/html":{"schema":{"type":"string"}}}},"403":{"description":"Invalid token signature"},"404":{"description":"Token not found"}}}},"/audit":{"get":{"tags":["Audit"],"summary":"View audit log","description":"Displays paginated approval and rejection history (most recent first).\nShows timestamp, container, action, old/new limits, and result status.\n","operationId":"getAuditLog","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1},"description":"Page number (1-indexed)"},{"name":"per_page","in":"query","schema":{"type":"integer","minimum":5,"maximum":100,"default":20},"description":"Entries per page"}],"responses":{"200":{"description":"HTML page with audit entries","content":{"text/html":{"schema":{"type":"string"}}}}}}}},"components":{"schemas":{"HealthResponse":{"type":"object","properties":{"status":{"type":"string","example":"ok"}}}}}}