phase 3: control loop — scheduler, actuator, learning, notifier, policy, API endpoints
Implemented the full OODA control loop: Scheduler: - Check_defs runner with bounded worker pool (errgroup) - Signal dedup via partial unique index (UpsertSignal) - Recovery auto-resolves open signals - Metrics writing (InsertMetricSample) and entity_status updates - Housekeeping (idempotency-key prune) - Graceful shutdown via ctx cancellation Actuator: - Auto-act signal consumer with FOR UPDATE SKIP LOCKED pattern - Per-target serialization with pg_advisory_xact_lock - Circuit breaker per target host (N consecutive failures → open) - Autonomy kill-switch (global.auto_act, never_auto_act.<slug>) - Execution record lifecycle (proposed → running → completed) Learning engine: - Hourly feedback extraction past watermark - Wilson score confidence lower bound (conservative for small N) - Pattern status: hypothesized → validated (N≥5, confidence ≥0.7) - Anomaly quarantine for burst feedback - Cap confidence by sample_size/5 (nothing confident before 5 samples) Notifier: - Approval token generation (HMAC single-use, hashed at rest) - Pending approval expiry detection - DB rendezvous pattern (no service-to-service RPC) Policy classifier: - Risk class resolution from policy tables - Autonomy checks (global + per-entity kill-switch) - Blast radius computation - Classification routes: auto-act / escalate / hold API endpoints (31 endpoints implemented): - Checks: ListChecks, CreateCheck, PatchCheck - Classifications: ListClassifications - Executions: ListExecutions, GetExecution, RequestExecution, CancelExecution - Approvals: ListApprovals, DecideApproval - Patterns: ListPatterns, PatchPattern - Skills: ListSkills, PatchSkill, ListSkillVersions - Policy: ListApprovalRules, CreateApprovalRule, PatchApprovalRule, GetAutonomySettings, PatchAutonomySettings, ListRiskClasses - Relationships: CreateRelationship, EndRelationship - Entity types: CreateEntityType, PatchEntityType - Metrics: QueryMetrics, GetTrends - Knowledge: SearchKnowledge, GetEntityKnowledge (stubs) - Agent activity: QueryAgentActivity (stub) Infrastructure: - Migration 009: knowledge_entities table with FTS indexes - Config: scheduler/notifier/actuator/learning env vars - sqlc: 30+ new Phase 3 queries - Integration tests for all new endpoints - go.sum updated with golang.org/x/sync
This commit is contained in:
@@ -1,131 +1,6 @@
|
||||
package httpapi
|
||||
|
||||
// Stubs for operations landing later in Phase 2/3. Each returns 501
|
||||
// problem+json via errNotImplemented. Regenerate the list when the spec
|
||||
// grows: the compiler enforces interface completeness either way.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/dtoro/oikos/internal/httpapi/gen"
|
||||
)
|
||||
|
||||
func (s *Server) QueryAgentActivity(ctx context.Context, request gen.QueryAgentActivityRequestObject) (gen.QueryAgentActivityResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListApprovals(ctx context.Context, request gen.ListApprovalsRequestObject) (gen.ListApprovalsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) DecideApproval(ctx context.Context, request gen.DecideApprovalRequestObject) (gen.DecideApprovalResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListChecks(ctx context.Context, request gen.ListChecksRequestObject) (gen.ListChecksResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) CreateCheck(ctx context.Context, request gen.CreateCheckRequestObject) (gen.CreateCheckResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) PatchCheck(ctx context.Context, request gen.PatchCheckRequestObject) (gen.PatchCheckResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListClassifications(ctx context.Context, request gen.ListClassificationsRequestObject) (gen.ListClassificationsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListExecutions(ctx context.Context, request gen.ListExecutionsRequestObject) (gen.ListExecutionsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) RequestExecution(ctx context.Context, request gen.RequestExecutionRequestObject) (gen.RequestExecutionResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) GetExecution(ctx context.Context, request gen.GetExecutionRequestObject) (gen.GetExecutionResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) CancelExecution(ctx context.Context, request gen.CancelExecutionRequestObject) (gen.CancelExecutionResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) SearchKnowledge(ctx context.Context, request gen.SearchKnowledgeRequestObject) (gen.SearchKnowledgeResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) GetEntityKnowledge(ctx context.Context, request gen.GetEntityKnowledgeRequestObject) (gen.GetEntityKnowledgeResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) QueryMetrics(ctx context.Context, request gen.QueryMetricsRequestObject) (gen.QueryMetricsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) CreateEntityType(ctx context.Context, request gen.CreateEntityTypeRequestObject) (gen.CreateEntityTypeResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) PatchEntityType(ctx context.Context, request gen.PatchEntityTypeRequestObject) (gen.PatchEntityTypeResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListPatterns(ctx context.Context, request gen.ListPatternsRequestObject) (gen.ListPatternsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) PatchPattern(ctx context.Context, request gen.PatchPatternRequestObject) (gen.PatchPatternResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListSkills(ctx context.Context, request gen.ListSkillsRequestObject) (gen.ListSkillsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) PatchSkill(ctx context.Context, request gen.PatchSkillRequestObject) (gen.PatchSkillResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListSkillVersions(ctx context.Context, request gen.ListSkillVersionsRequestObject) (gen.ListSkillVersionsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListApprovalRules(ctx context.Context, request gen.ListApprovalRulesRequestObject) (gen.ListApprovalRulesResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) CreateApprovalRule(ctx context.Context, request gen.CreateApprovalRuleRequestObject) (gen.CreateApprovalRuleResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) PatchApprovalRule(ctx context.Context, request gen.PatchApprovalRuleRequestObject) (gen.PatchApprovalRuleResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) GetAutonomySettings(ctx context.Context, request gen.GetAutonomySettingsRequestObject) (gen.GetAutonomySettingsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) PatchAutonomySettings(ctx context.Context, request gen.PatchAutonomySettingsRequestObject) (gen.PatchAutonomySettingsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) ListRiskClasses(ctx context.Context, request gen.ListRiskClassesRequestObject) (gen.ListRiskClassesResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) EndRelationship(ctx context.Context, request gen.EndRelationshipRequestObject) (gen.EndRelationshipResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) CreateRelationship(ctx context.Context, request gen.CreateRelationshipRequestObject) (gen.CreateRelationshipResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func (s *Server) GetTrends(ctx context.Context, request gen.GetTrendsRequestObject) (gen.GetTrendsResponseObject, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
// Remaining stubs for endpoints that depend on tables not yet created
|
||||
// (knowledge_entities, agent_activity). These are kept here because the
|
||||
// phase3.go file already defines them; this file is deliberately empty.
|
||||
// The stubs live in phase3.go as simple errNotImplemented returns.
|
||||
Reference in New Issue
Block a user