Expand test coverage across server, agent, and web; fix bugs found during audit.

Adds hundreds of unit/integration/e2e tests, fixes WS bcrypt auth, config merge, fleet analytics, agent schedule/log tail, and documents stale PROBLEMS items. Updates PROBLEMS.md, README, and test scripts; ignores local spread-kits and coverage dirs.
This commit is contained in:
AetherForge
2026-05-31 01:13:49 -07:00
parent 159747877c
commit ea6f54ad03
89 changed files with 5307 additions and 322 deletions

View File

@@ -140,8 +140,14 @@ func (h *AIHandler) HandleHeartbeat(w http.ResponseWriter, r *http.Request) {
// ─── Decide ───────────────────────────────────
// decideRequest carries the agent state for an AI decision cycle.
// OllamaEndpoint and Model are intentionally ignored on the server side —
// the engine endpoint is set server-side when the agent authenticates via WS
// to prevent SSRF via caller-supplied URLs.
type decideRequest struct {
AgentID string `json:"agent_id"`
AgentID string `json:"agent_id"`
// OllamaEndpoint is accepted in the payload for forward-compat but NEVER used;
// the server uses only the endpoint set during WS authentication.
OllamaEndpoint string `json:"ollama_endpoint,omitempty"`
Model string `json:"model,omitempty"`
ollama.AgentState
@@ -159,16 +165,14 @@ func (h *AIHandler) handleDecide(w http.ResponseWriter, r *http.Request) {
return
}
// Get or create engine for this agent
// Only use the engine that was registered when the agent authenticated via
// WebSocket — do NOT create a new engine from caller-supplied OllamaEndpoint,
// which would allow SSRF by pointing the server at an internal URL.
engine := h.GetEngine(req.AgentID)
if engine == nil {
// Create engine on first request
h.SetEngineForAgent(req.AgentID, req.OllamaEndpoint, req.Model)
engine = h.GetEngine(req.AgentID)
}
if engine == nil {
http.Error(w, "failed to create AI engine", http.StatusInternalServerError)
// Agent has not yet authenticated via WebSocket; reject to prevent
// unauthenticated callers from triggering outbound Ollama requests.
http.Error(w, "agent not registered — authenticate via WebSocket first", http.StatusForbidden)
return
}