Files
oikos/internal/db/sqlcgen/operations.sql.go
dtoro 4e294b3630
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
0.22.0 — full MCP agent surface: 19 new tools, async run, session reliability
Stage 1 — Foundation:
- Target validation: iptables + systemctl/docker target-type gates
- Async run for long-running commands (sleep/wait/poll loops)
- audit_log.session_id plumbing (SQL, sqlcgen, 18 call sites)

Stage 2 — External agent observe (11 tools):
- get_dashboard_summary, get_ontology, list_checks, list_executions
- get_knowledge_revisions, get_knowledge_duplicates, get_knowledge_orphans
- list_knowledge_tags, list_entity_sessions, find_entities_by
- 3 resource templates: oikos://entity/{slug}, knowledge/{id}, execution/{id}

Stage 3 — Nomos reliability:
- complete_task(success) refused without verification (upgraded from warn)
- sessionHasPlan excludes replaced steps (forces propose_plan after reopen)
- Bash syntax validation in run() (rejects literal \n, flag-space typos)
- Scope gate in SOUL.md (ask before pivoting to unrelated subsystem)

Stage 4 — External agent act (9 mutation tools):
- ack_signal, resolve_signal, mute_signal, cancel_execution
- update_check, delete_knowledge, restore_knowledge
- merge_knowledge, rename_knowledge_tag
2026-08-04 23:51:55 +02:00

1497 lines
37 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: operations.sql
package sqlcgen
import (
"context"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
const getApprovalByID = `-- name: GetApprovalByID :one
SELECT entity_id, subject_entity_id, action, risk_class, kind, payload, status, token_hash, expires_at, decided_at, decided_by, created_at, matrix_event_id, alert_sent_at FROM approvals WHERE entity_id = $1
`
func (q *Queries) GetApprovalByID(ctx context.Context, entityID uuid.UUID) (Approval, error) {
row := q.db.QueryRow(ctx, getApprovalByID, entityID)
var i Approval
err := row.Scan(
&i.EntityID,
&i.SubjectEntityID,
&i.Action,
&i.RiskClass,
&i.Kind,
&i.Payload,
&i.Status,
&i.TokenHash,
&i.ExpiresAt,
&i.DecidedAt,
&i.DecidedBy,
&i.CreatedAt,
&i.MatrixEventID,
&i.AlertSentAt,
)
return i, err
}
const getAutonomySetting = `-- name: GetAutonomySetting :one
SELECT value FROM autonomy_settings WHERE key = $1
`
func (q *Queries) GetAutonomySetting(ctx context.Context, key string) (string, error) {
row := q.db.QueryRow(ctx, getAutonomySetting, key)
var value string
err := row.Scan(&value)
return value, err
}
const getCheckDef = `-- name: GetCheckDef :one
SELECT entity_id, target_id, target_type, kind, config, interval_s, timeout_s, zone, enabled, updated_at, last_run_at, last_health FROM check_defs WHERE entity_id = $1
`
func (q *Queries) GetCheckDef(ctx context.Context, entityID uuid.UUID) (CheckDef, error) {
row := q.db.QueryRow(ctx, getCheckDef, entityID)
var i CheckDef
err := row.Scan(
&i.EntityID,
&i.TargetID,
&i.TargetType,
&i.Kind,
&i.Config,
&i.IntervalS,
&i.TimeoutS,
&i.Zone,
&i.Enabled,
&i.UpdatedAt,
&i.LastRunAt,
&i.LastHealth,
)
return i, err
}
const getEntityStatus = `-- name: GetEntityStatus :one
SELECT entity_id, health, last_check_at, details, updated_at FROM entity_status WHERE entity_id = $1
`
func (q *Queries) GetEntityStatus(ctx context.Context, entityID uuid.UUID) (EntityStatus, error) {
row := q.db.QueryRow(ctx, getEntityStatus, entityID)
var i EntityStatus
err := row.Scan(
&i.EntityID,
&i.Health,
&i.LastCheckAt,
&i.Details,
&i.UpdatedAt,
)
return i, err
}
const getExecution = `-- name: GetExecution :one
SELECT entity_id, classification_id, signal_entity_id, target_entity_id, action, risk_class, approval_id, agent_id, skill_id, skill_version, status, result, duration_ms, verified, correlation_id, started_at, completed_at, created_at FROM executions WHERE entity_id = $1
`
func (q *Queries) GetExecution(ctx context.Context, entityID uuid.UUID) (Execution, error) {
row := q.db.QueryRow(ctx, getExecution, entityID)
var i Execution
err := row.Scan(
&i.EntityID,
&i.ClassificationID,
&i.SignalEntityID,
&i.TargetEntityID,
&i.Action,
&i.RiskClass,
&i.ApprovalID,
&i.AgentID,
&i.SkillID,
&i.SkillVersion,
&i.Status,
&i.Result,
&i.DurationMs,
&i.Verified,
&i.CorrelationID,
&i.StartedAt,
&i.CompletedAt,
&i.CreatedAt,
)
return i, err
}
const getFeedbackAfterWatermark = `-- name: GetFeedbackAfterWatermark :many
SELECT f.entity_id, f.execution_id, f.outcome, f.observation, f.lesson,
f.unexpected_side_effects, f.tags, f.created_at,
e.action, e.risk_class, e.target_entity_id,
et.name AS applies_type
FROM feedback f
JOIN executions e ON e.entity_id = f.execution_id
JOIN entities ent ON ent.id = e.target_entity_id
JOIN entity_types et ON et.name = ent.type
WHERE f.created_at > $1
ORDER BY f.created_at ASC
`
type GetFeedbackAfterWatermarkRow struct {
EntityID uuid.UUID
ExecutionID uuid.UUID
Outcome string
Observation *string
Lesson *string
UnexpectedSideEffects []string
Tags []string
CreatedAt time.Time
Action string
RiskClass string
TargetEntityID *uuid.UUID
AppliesType string
}
func (q *Queries) GetFeedbackAfterWatermark(ctx context.Context, createdAt time.Time) ([]GetFeedbackAfterWatermarkRow, error) {
rows, err := q.db.Query(ctx, getFeedbackAfterWatermark, createdAt)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetFeedbackAfterWatermarkRow
for rows.Next() {
var i GetFeedbackAfterWatermarkRow
if err := rows.Scan(
&i.EntityID,
&i.ExecutionID,
&i.Outcome,
&i.Observation,
&i.Lesson,
&i.UnexpectedSideEffects,
&i.Tags,
&i.CreatedAt,
&i.Action,
&i.RiskClass,
&i.TargetEntityID,
&i.AppliesType,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getIdempotentResponse = `-- name: GetIdempotentResponse :one
SELECT response_code, response_body, request_hash FROM idempotency_keys
WHERE actor = $1 AND key = $2
`
type GetIdempotentResponseParams struct {
Actor string
Key string
}
type GetIdempotentResponseRow struct {
ResponseCode *int32
ResponseBody []byte
RequestHash string
}
func (q *Queries) GetIdempotentResponse(ctx context.Context, arg GetIdempotentResponseParams) (GetIdempotentResponseRow, error) {
row := q.db.QueryRow(ctx, getIdempotentResponse, arg.Actor, arg.Key)
var i GetIdempotentResponseRow
err := row.Scan(&i.ResponseCode, &i.ResponseBody, &i.RequestHash)
return i, err
}
const getOpenSignalsForAutoAct = `-- name: GetOpenSignalsForAutoAct :many
SELECT s.entity_id, s.kind, s.severity, s.target_entity_id, s.check_id, s.evidence, s.likely_cause, s.state, s.occurrence_count, s.first_seen_at, s.last_seen_at, s.flap_count, s.hold_down_until, s.mute_until, s.created_at, s.updated_at, c.entity_id AS classification_id, c.action, c.risk_class, c.route,
c.blast_radius, c.correlation_id, c.reasoning
FROM classifications c
JOIN signals s ON s.entity_id = c.signal_entity_id
LEFT JOIN executions e ON e.classification_id = c.entity_id
WHERE c.route = 'auto-act'
AND e.entity_id IS NULL
AND (s.hold_down_until IS NULL OR s.hold_down_until < now())
AND (s.mute_until IS NULL OR s.mute_until < now())
ORDER BY s.last_seen_at ASC
LIMIT $1
`
type GetOpenSignalsForAutoActRow struct {
EntityID uuid.UUID
Kind string
Severity string
TargetEntityID *uuid.UUID
CheckID *uuid.UUID
Evidence *string
LikelyCause *string
State string
OccurrenceCount int32
FirstSeenAt time.Time
LastSeenAt time.Time
FlapCount int32
HoldDownUntil *time.Time
MuteUntil *time.Time
CreatedAt time.Time
UpdatedAt time.Time
ClassificationID uuid.UUID
Action string
RiskClass string
Route string
BlastRadius []uuid.UUID
CorrelationID string
Reasoning []byte
}
// Signals with auto-act classifications that haven't been executed yet
func (q *Queries) GetOpenSignalsForAutoAct(ctx context.Context, limit int32) ([]GetOpenSignalsForAutoActRow, error) {
rows, err := q.db.Query(ctx, getOpenSignalsForAutoAct, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetOpenSignalsForAutoActRow
for rows.Next() {
var i GetOpenSignalsForAutoActRow
if err := rows.Scan(
&i.EntityID,
&i.Kind,
&i.Severity,
&i.TargetEntityID,
&i.CheckID,
&i.Evidence,
&i.LikelyCause,
&i.State,
&i.OccurrenceCount,
&i.FirstSeenAt,
&i.LastSeenAt,
&i.FlapCount,
&i.HoldDownUntil,
&i.MuteUntil,
&i.CreatedAt,
&i.UpdatedAt,
&i.ClassificationID,
&i.Action,
&i.RiskClass,
&i.Route,
&i.BlastRadius,
&i.CorrelationID,
&i.Reasoning,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getPattern = `-- name: GetPattern :one
SELECT entity_id, applies_type, action, pattern, confidence, evidence_count, success_count, failure_count, status, quarantined, version, last_validated_at, created_at FROM patterns WHERE applies_type = $1 AND action = $2
`
type GetPatternParams struct {
AppliesType string
Action string
}
func (q *Queries) GetPattern(ctx context.Context, arg GetPatternParams) (Pattern, error) {
row := q.db.QueryRow(ctx, getPattern, arg.AppliesType, arg.Action)
var i Pattern
err := row.Scan(
&i.EntityID,
&i.AppliesType,
&i.Action,
&i.Pattern,
&i.Confidence,
&i.EvidenceCount,
&i.SuccessCount,
&i.FailureCount,
&i.Status,
&i.Quarantined,
&i.Version,
&i.LastValidatedAt,
&i.CreatedAt,
)
return i, err
}
const insertApproval = `-- name: InsertApproval :exec
INSERT INTO approvals (entity_id, subject_entity_id, action, risk_class, kind,
payload, status, token_hash, expires_at)
VALUES ($1, $2, $3, $4, $5, $6, 'pending', $7, $8)
`
type InsertApprovalParams struct {
EntityID uuid.UUID
SubjectEntityID *uuid.UUID
Action string
RiskClass string
Kind string
Payload []byte
TokenHash *string
ExpiresAt time.Time
}
func (q *Queries) InsertApproval(ctx context.Context, arg InsertApprovalParams) error {
_, err := q.db.Exec(ctx, insertApproval,
arg.EntityID,
arg.SubjectEntityID,
arg.Action,
arg.RiskClass,
arg.Kind,
arg.Payload,
arg.TokenHash,
arg.ExpiresAt,
)
return err
}
const insertAuditEntry = `-- name: InsertAuditEntry :exec
INSERT INTO audit_log (actor_type, actor_id, action, entity_id, method, path,
status_code, detail, source_ip, correlation_id, session_id)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
`
type InsertAuditEntryParams struct {
ActorType string
ActorID *uuid.UUID
Action string
EntityID *uuid.UUID
Method *string
Path *string
StatusCode *int32
Detail []byte
SourceIp *string
CorrelationID *string
SessionID *uuid.UUID
}
func (q *Queries) InsertAuditEntry(ctx context.Context, arg InsertAuditEntryParams) error {
_, err := q.db.Exec(ctx, insertAuditEntry,
arg.ActorType,
arg.ActorID,
arg.Action,
arg.EntityID,
arg.Method,
arg.Path,
arg.StatusCode,
arg.Detail,
arg.SourceIp,
arg.CorrelationID,
arg.SessionID,
)
return err
}
const insertCheckDef = `-- name: InsertCheckDef :exec
INSERT INTO check_defs (entity_id, target_id, target_type, kind, config, interval_s, timeout_s, zone, enabled)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
`
type InsertCheckDefParams struct {
EntityID uuid.UUID
TargetID *uuid.UUID
TargetType *string
Kind string
Config []byte
IntervalS int32
TimeoutS int32
Zone *string
Enabled bool
}
func (q *Queries) InsertCheckDef(ctx context.Context, arg InsertCheckDefParams) error {
_, err := q.db.Exec(ctx, insertCheckDef,
arg.EntityID,
arg.TargetID,
arg.TargetType,
arg.Kind,
arg.Config,
arg.IntervalS,
arg.TimeoutS,
arg.Zone,
arg.Enabled,
)
return err
}
const insertEvent = `-- name: InsertEvent :one
INSERT INTO events (type, entity_id, severity, source, data, correlation_id)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id, ts
`
type InsertEventParams struct {
Type string
EntityID *uuid.UUID
Severity string
Source string
Data []byte
CorrelationID *string
}
type InsertEventRow struct {
ID int64
Ts time.Time
}
func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) (InsertEventRow, error) {
row := q.db.QueryRow(ctx, insertEvent,
arg.Type,
arg.EntityID,
arg.Severity,
arg.Source,
arg.Data,
arg.CorrelationID,
)
var i InsertEventRow
err := row.Scan(&i.ID, &i.Ts)
return i, err
}
const insertExecution = `-- name: InsertExecution :exec
INSERT INTO executions (entity_id, classification_id, signal_entity_id,
target_entity_id, action, risk_class, approval_id, agent_id,
skill_id, skill_version, status, correlation_id)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, 'proposed', $11)
`
type InsertExecutionParams struct {
EntityID uuid.UUID
ClassificationID *uuid.UUID
SignalEntityID *uuid.UUID
TargetEntityID *uuid.UUID
Action string
RiskClass string
ApprovalID *uuid.UUID
AgentID *uuid.UUID
SkillID *uuid.UUID
SkillVersion *int32
CorrelationID string
}
func (q *Queries) InsertExecution(ctx context.Context, arg InsertExecutionParams) error {
_, err := q.db.Exec(ctx, insertExecution,
arg.EntityID,
arg.ClassificationID,
arg.SignalEntityID,
arg.TargetEntityID,
arg.Action,
arg.RiskClass,
arg.ApprovalID,
arg.AgentID,
arg.SkillID,
arg.SkillVersion,
arg.CorrelationID,
)
return err
}
const insertMetricSample = `-- name: InsertMetricSample :exec
INSERT INTO metric_samples (entity_id, metric, value, tags, ts)
VALUES ($1, $2, $3, $4, now())
`
type InsertMetricSampleParams struct {
EntityID uuid.UUID
Metric string
Value float64
Tags []byte
}
func (q *Queries) InsertMetricSample(ctx context.Context, arg InsertMetricSampleParams) error {
_, err := q.db.Exec(ctx, insertMetricSample,
arg.EntityID,
arg.Metric,
arg.Value,
arg.Tags,
)
return err
}
const listApprovalRules = `-- name: ListApprovalRules :many
SELECT id, entity_type, action, risk_class, autonomy_level, scope_entity, version, updated_at FROM approval_rules ORDER BY entity_type, action
`
func (q *Queries) ListApprovalRules(ctx context.Context) ([]ApprovalRule, error) {
rows, err := q.db.Query(ctx, listApprovalRules)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ApprovalRule
for rows.Next() {
var i ApprovalRule
if err := rows.Scan(
&i.ID,
&i.EntityType,
&i.Action,
&i.RiskClass,
&i.AutonomyLevel,
&i.ScopeEntity,
&i.Version,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listApprovals = `-- name: ListApprovals :many
SELECT a.entity_id, a.subject_entity_id, a.action, a.risk_class, a.kind, a.payload, a.status, a.token_hash, a.expires_at, a.decided_at, a.decided_by, a.created_at, a.matrix_event_id, a.alert_sent_at, e.slug AS subject_slug
FROM approvals a
JOIN entities e ON e.id = a.subject_entity_id
WHERE ($1::text IS NULL OR a.status = $1)
AND ($2::text IS NULL OR e.slug > $2)
ORDER BY e.slug
LIMIT $3
`
type ListApprovalsParams struct {
Status *string
Cursor *string
Lim int32
}
type ListApprovalsRow struct {
EntityID uuid.UUID
SubjectEntityID *uuid.UUID
Action string
RiskClass string
Kind string
Payload []byte
Status string
TokenHash *string
ExpiresAt time.Time
DecidedAt *time.Time
DecidedBy *uuid.UUID
CreatedAt time.Time
MatrixEventID *string
AlertSentAt *time.Time
SubjectSlug string
}
func (q *Queries) ListApprovals(ctx context.Context, arg ListApprovalsParams) ([]ListApprovalsRow, error) {
rows, err := q.db.Query(ctx, listApprovals, arg.Status, arg.Cursor, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListApprovalsRow
for rows.Next() {
var i ListApprovalsRow
if err := rows.Scan(
&i.EntityID,
&i.SubjectEntityID,
&i.Action,
&i.RiskClass,
&i.Kind,
&i.Payload,
&i.Status,
&i.TokenHash,
&i.ExpiresAt,
&i.DecidedAt,
&i.DecidedBy,
&i.CreatedAt,
&i.MatrixEventID,
&i.AlertSentAt,
&i.SubjectSlug,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listClassifications = `-- name: ListClassifications :many
SELECT c.entity_id, c.signal_entity_id, c.target_entity_id, c.action,
c.recommended_action, c.risk_class, c.route, c.blast_radius,
c.pattern_confidence, c.skill_id, c.autonomy_check, c.reasoning,
c.correlation_id, c.created_at,
e.slug AS target_slug
FROM classifications c
JOIN entities e ON e.id = c.target_entity_id
WHERE ($1::text IS NULL OR c.route = $1)
AND ($2::text IS NULL OR e.slug > $2)
ORDER BY e.slug
LIMIT $3
`
type ListClassificationsParams struct {
Route *string
Cursor *string
Lim int32
}
type ListClassificationsRow struct {
EntityID uuid.UUID
SignalEntityID *uuid.UUID
TargetEntityID *uuid.UUID
Action string
RecommendedAction []byte
RiskClass string
Route string
BlastRadius []uuid.UUID
PatternConfidence *float32
SkillID *uuid.UUID
AutonomyCheck *string
Reasoning []byte
CorrelationID string
CreatedAt time.Time
TargetSlug string
}
func (q *Queries) ListClassifications(ctx context.Context, arg ListClassificationsParams) ([]ListClassificationsRow, error) {
rows, err := q.db.Query(ctx, listClassifications, arg.Route, arg.Cursor, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListClassificationsRow
for rows.Next() {
var i ListClassificationsRow
if err := rows.Scan(
&i.EntityID,
&i.SignalEntityID,
&i.TargetEntityID,
&i.Action,
&i.RecommendedAction,
&i.RiskClass,
&i.Route,
&i.BlastRadius,
&i.PatternConfidence,
&i.SkillID,
&i.AutonomyCheck,
&i.Reasoning,
&i.CorrelationID,
&i.CreatedAt,
&i.TargetSlug,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listEnabledCheckDefs = `-- name: ListEnabledCheckDefs :many
SELECT cd.entity_id, cd.target_id, cd.target_type, cd.kind, cd.config,
cd.interval_s, cd.timeout_s, cd.zone, cd.enabled, cd.updated_at,
e.slug AS entity_slug
FROM check_defs cd
JOIN entities e ON e.id = cd.entity_id
LEFT JOIN entities tgt ON tgt.id = cd.target_id
WHERE cd.enabled = true
AND (tgt.id IS NULL OR tgt.state IS NULL OR tgt.state NOT IN ('deprecated', 'destroyed'))
AND (cd.last_run_at IS NULL
OR cd.last_run_at <= now() - make_interval(secs => cd.interval_s))
`
type ListEnabledCheckDefsRow struct {
EntityID uuid.UUID
TargetID *uuid.UUID
TargetType *string
Kind string
Config []byte
IntervalS int32
TimeoutS int32
Zone *string
Enabled bool
UpdatedAt time.Time
EntitySlug string
}
// =====================================================================
// Phase 3 queries
// =====================================================================
// Enabled AND due. interval_s used to be selected but never filtered on, so
// every check ran on every 30s pass and the declared intervals meant nothing.
// NULL last_run_at = never run = due now.
func (q *Queries) ListEnabledCheckDefs(ctx context.Context) ([]ListEnabledCheckDefsRow, error) {
rows, err := q.db.Query(ctx, listEnabledCheckDefs)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListEnabledCheckDefsRow
for rows.Next() {
var i ListEnabledCheckDefsRow
if err := rows.Scan(
&i.EntityID,
&i.TargetID,
&i.TargetType,
&i.Kind,
&i.Config,
&i.IntervalS,
&i.TimeoutS,
&i.Zone,
&i.Enabled,
&i.UpdatedAt,
&i.EntitySlug,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listEvents = `-- name: ListEvents :many
SELECT id, ts, type, entity_id, severity, source, data, correlation_id
FROM events
WHERE ($1::text IS NULL OR type = $1)
AND ($2::uuid IS NULL OR entity_id = $2)
AND ($3::text IS NULL OR severity = $3)
AND ($4::text IS NULL OR correlation_id = $4)
AND ($5::timestamptz IS NULL OR ts >= $5)
AND ($6::timestamptz IS NULL OR ts <= $6)
AND ($7::bigint IS NULL OR id < $7)
ORDER BY id DESC
LIMIT $8
`
type ListEventsParams struct {
Type *string
EntityID *uuid.UUID
Severity *string
CorrelationID *string
FromTs *time.Time
ToTs *time.Time
BeforeID *int64
Lim int32
}
func (q *Queries) ListEvents(ctx context.Context, arg ListEventsParams) ([]Event, error) {
rows, err := q.db.Query(ctx, listEvents,
arg.Type,
arg.EntityID,
arg.Severity,
arg.CorrelationID,
arg.FromTs,
arg.ToTs,
arg.BeforeID,
arg.Lim,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Event
for rows.Next() {
var i Event
if err := rows.Scan(
&i.ID,
&i.Ts,
&i.Type,
&i.EntityID,
&i.Severity,
&i.Source,
&i.Data,
&i.CorrelationID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listEventsAfter = `-- name: ListEventsAfter :many
SELECT id, ts, type, entity_id, severity, source, data, correlation_id
FROM events WHERE id > $1 ORDER BY id ASC LIMIT $2
`
type ListEventsAfterParams struct {
ID int64
Limit int32
}
func (q *Queries) ListEventsAfter(ctx context.Context, arg ListEventsAfterParams) ([]Event, error) {
rows, err := q.db.Query(ctx, listEventsAfter, arg.ID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Event
for rows.Next() {
var i Event
if err := rows.Scan(
&i.ID,
&i.Ts,
&i.Type,
&i.EntityID,
&i.Severity,
&i.Source,
&i.Data,
&i.CorrelationID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listExecutions = `-- name: ListExecutions :many
SELECT e.entity_id, e.classification_id, e.signal_entity_id, e.target_entity_id,
e.action, e.risk_class, e.approval_id, e.agent_id,
e.skill_id, e.skill_version, e.status, e.result, e.duration_ms,
e.verified, e.correlation_id, e.started_at, e.completed_at, e.created_at,
te.slug AS target_slug
FROM executions e
JOIN entities te ON te.id = e.target_entity_id
WHERE ($1::text IS NULL OR e.status = $1)
AND ($2::text IS NULL OR te.slug > $2)
ORDER BY te.slug
LIMIT $3
`
type ListExecutionsParams struct {
Status *string
Cursor *string
Lim int32
}
type ListExecutionsRow struct {
EntityID uuid.UUID
ClassificationID *uuid.UUID
SignalEntityID *uuid.UUID
TargetEntityID *uuid.UUID
Action string
RiskClass string
ApprovalID *uuid.UUID
AgentID *uuid.UUID
SkillID *uuid.UUID
SkillVersion *int32
Status string
Result []byte
DurationMs *int32
Verified bool
CorrelationID string
StartedAt *time.Time
CompletedAt *time.Time
CreatedAt time.Time
TargetSlug string
}
func (q *Queries) ListExecutions(ctx context.Context, arg ListExecutionsParams) ([]ListExecutionsRow, error) {
rows, err := q.db.Query(ctx, listExecutions, arg.Status, arg.Cursor, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListExecutionsRow
for rows.Next() {
var i ListExecutionsRow
if err := rows.Scan(
&i.EntityID,
&i.ClassificationID,
&i.SignalEntityID,
&i.TargetEntityID,
&i.Action,
&i.RiskClass,
&i.ApprovalID,
&i.AgentID,
&i.SkillID,
&i.SkillVersion,
&i.Status,
&i.Result,
&i.DurationMs,
&i.Verified,
&i.CorrelationID,
&i.StartedAt,
&i.CompletedAt,
&i.CreatedAt,
&i.TargetSlug,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPatterns = `-- name: ListPatterns :many
SELECT p.entity_id, p.applies_type, p.action, p.pattern, p.confidence, p.evidence_count, p.success_count, p.failure_count, p.status, p.quarantined, p.version, p.last_validated_at, p.created_at FROM patterns p
WHERE ($1::text IS NULL OR p.status = $1)
ORDER BY p.applies_type, p.action
`
func (q *Queries) ListPatterns(ctx context.Context, status *string) ([]Pattern, error) {
rows, err := q.db.Query(ctx, listPatterns, status)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Pattern
for rows.Next() {
var i Pattern
if err := rows.Scan(
&i.EntityID,
&i.AppliesType,
&i.Action,
&i.Pattern,
&i.Confidence,
&i.EvidenceCount,
&i.SuccessCount,
&i.FailureCount,
&i.Status,
&i.Quarantined,
&i.Version,
&i.LastValidatedAt,
&i.CreatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listRiskClasses = `-- name: ListRiskClasses :many
SELECT name, description, approval_required, autonomy_allowed FROM risk_classes ORDER BY name
`
func (q *Queries) ListRiskClasses(ctx context.Context) ([]RiskClass, error) {
rows, err := q.db.Query(ctx, listRiskClasses)
if err != nil {
return nil, err
}
defer rows.Close()
var items []RiskClass
for rows.Next() {
var i RiskClass
if err := rows.Scan(
&i.Name,
&i.Description,
&i.ApprovalRequired,
&i.AutonomyAllowed,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listSignals = `-- name: ListSignals :many
SELECT sig.entity_id, se.slug, sig.kind, sig.severity, sig.state,
te.slug AS target_slug, sig.check_id, sig.evidence, sig.likely_cause,
sig.occurrence_count, sig.flap_count, sig.hold_down_until,
sig.mute_until, sig.first_seen_at, sig.last_seen_at
FROM signals sig
JOIN entities se ON se.id = sig.entity_id
LEFT JOIN entities te ON te.id = sig.target_entity_id
WHERE ($1::text IS NULL OR sig.state = $1)
AND ($2::text IS NULL OR sig.severity = $2)
AND ($3::text IS NULL OR te.slug = $3)
AND ($4::text IS NULL OR sig.kind = $4)
AND ($5::text IS NULL OR se.slug > $5)
ORDER BY se.slug
LIMIT $6
`
type ListSignalsParams struct {
State *string
Severity *string
Target *string
Kind *string
Cursor *string
Lim int32
}
type ListSignalsRow struct {
EntityID uuid.UUID
Slug string
Kind string
Severity string
State string
TargetSlug *string
CheckID *uuid.UUID
Evidence *string
LikelyCause *string
OccurrenceCount int32
FlapCount int32
HoldDownUntil *time.Time
MuteUntil *time.Time
FirstSeenAt time.Time
LastSeenAt time.Time
}
func (q *Queries) ListSignals(ctx context.Context, arg ListSignalsParams) ([]ListSignalsRow, error) {
rows, err := q.db.Query(ctx, listSignals,
arg.State,
arg.Severity,
arg.Target,
arg.Kind,
arg.Cursor,
arg.Lim,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListSignalsRow
for rows.Next() {
var i ListSignalsRow
if err := rows.Scan(
&i.EntityID,
&i.Slug,
&i.Kind,
&i.Severity,
&i.State,
&i.TargetSlug,
&i.CheckID,
&i.Evidence,
&i.LikelyCause,
&i.OccurrenceCount,
&i.FlapCount,
&i.HoldDownUntil,
&i.MuteUntil,
&i.FirstSeenAt,
&i.LastSeenAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listSkills = `-- name: ListSkills :many
SELECT entity_id, version, name, procedure, applies_type, action, pattern_ids, status, success_rate, changed_by, change_reason, last_used_at, created_at FROM skills
WHERE ($1::text IS NULL OR status = $1)
ORDER BY name, version DESC
`
func (q *Queries) ListSkills(ctx context.Context, status *string) ([]Skill, error) {
rows, err := q.db.Query(ctx, listSkills, status)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Skill
for rows.Next() {
var i Skill
if err := rows.Scan(
&i.EntityID,
&i.Version,
&i.Name,
&i.Procedure,
&i.AppliesType,
&i.Action,
&i.PatternIds,
&i.Status,
&i.SuccessRate,
&i.ChangedBy,
&i.ChangeReason,
&i.LastUsedAt,
&i.CreatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const markCheckRun = `-- name: MarkCheckRun :exec
UPDATE check_defs SET last_run_at = now(), last_health = $2 WHERE entity_id = $1
`
type MarkCheckRunParams struct {
EntityID uuid.UUID
LastHealth *string
}
func (q *Queries) MarkCheckRun(ctx context.Context, arg MarkCheckRunParams) error {
_, err := q.db.Exec(ctx, markCheckRun, arg.EntityID, arg.LastHealth)
return err
}
const putIdempotentResponse = `-- name: PutIdempotentResponse :exec
INSERT INTO idempotency_keys (actor, key, request_hash, response_code, response_body)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (actor, key) DO NOTHING
`
type PutIdempotentResponseParams struct {
Actor string
Key string
RequestHash string
ResponseCode *int32
ResponseBody []byte
}
func (q *Queries) PutIdempotentResponse(ctx context.Context, arg PutIdempotentResponseParams) error {
_, err := q.db.Exec(ctx, putIdempotentResponse,
arg.Actor,
arg.Key,
arg.RequestHash,
arg.ResponseCode,
arg.ResponseBody,
)
return err
}
const queryMetrics = `-- name: QueryMetrics :many
SELECT time_bucket($4::interval, ts) AS bucket,
entity_id, metric,
ROUND(avg(value)::numeric, 2) AS avg_val,
ROUND(min(value)::numeric, 2) AS min_val,
ROUND(max(value)::numeric, 2) AS max_val
FROM metric_samples
WHERE entity_id = $1
AND metric = $2
AND ts > $3
GROUP BY bucket, entity_id, metric
ORDER BY bucket DESC
`
type QueryMetricsParams struct {
EntityID uuid.UUID
Metric string
Ts time.Time
BucketInterval pgtype.Interval
}
type QueryMetricsRow struct {
Bucket interface{}
EntityID uuid.UUID
Metric string
AvgVal pgtype.Numeric
MinVal pgtype.Numeric
MaxVal pgtype.Numeric
}
func (q *Queries) QueryMetrics(ctx context.Context, arg QueryMetricsParams) ([]QueryMetricsRow, error) {
rows, err := q.db.Query(ctx, queryMetrics,
arg.EntityID,
arg.Metric,
arg.Ts,
arg.BucketInterval,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []QueryMetricsRow
for rows.Next() {
var i QueryMetricsRow
if err := rows.Scan(
&i.Bucket,
&i.EntityID,
&i.Metric,
&i.AvgVal,
&i.MinVal,
&i.MaxVal,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const updateApprovalStatus = `-- name: UpdateApprovalStatus :exec
UPDATE approvals SET status = $2, decided_at = now(), decided_by = $3
WHERE entity_id = $1 AND status = 'pending'
`
type UpdateApprovalStatusParams struct {
EntityID uuid.UUID
Status string
DecidedBy *uuid.UUID
}
func (q *Queries) UpdateApprovalStatus(ctx context.Context, arg UpdateApprovalStatusParams) error {
_, err := q.db.Exec(ctx, updateApprovalStatus, arg.EntityID, arg.Status, arg.DecidedBy)
return err
}
const updateCheckDef = `-- name: UpdateCheckDef :exec
UPDATE check_defs SET kind = $2, config = $3, interval_s = $4, timeout_s = $5,
target_id = $6, target_type = $7, zone = $8, enabled = $9, updated_at = now()
WHERE entity_id = $1
`
type UpdateCheckDefParams struct {
EntityID uuid.UUID
Kind string
Config []byte
IntervalS int32
TimeoutS int32
TargetID *uuid.UUID
TargetType *string
Zone *string
Enabled bool
}
func (q *Queries) UpdateCheckDef(ctx context.Context, arg UpdateCheckDefParams) error {
_, err := q.db.Exec(ctx, updateCheckDef,
arg.EntityID,
arg.Kind,
arg.Config,
arg.IntervalS,
arg.TimeoutS,
arg.TargetID,
arg.TargetType,
arg.Zone,
arg.Enabled,
)
return err
}
const updateExecutionStatus = `-- name: UpdateExecutionStatus :exec
UPDATE executions SET status = $2, result = $3, duration_ms = $4,
verified = $5, started_at = COALESCE(started_at, now()),
completed_at = CASE WHEN $2 IN ('completed','failed','cancelled') THEN now() ELSE completed_at END
WHERE entity_id = $1
`
type UpdateExecutionStatusParams struct {
EntityID uuid.UUID
Status string
Result []byte
DurationMs *int32
Verified bool
}
func (q *Queries) UpdateExecutionStatus(ctx context.Context, arg UpdateExecutionStatusParams) error {
_, err := q.db.Exec(ctx, updateExecutionStatus,
arg.EntityID,
arg.Status,
arg.Result,
arg.DurationMs,
arg.Verified,
)
return err
}
const updatePatternQuarantine = `-- name: UpdatePatternQuarantine :exec
UPDATE patterns SET quarantined = $2 WHERE entity_id = $1
`
type UpdatePatternQuarantineParams struct {
EntityID uuid.UUID
Quarantined bool
}
func (q *Queries) UpdatePatternQuarantine(ctx context.Context, arg UpdatePatternQuarantineParams) error {
_, err := q.db.Exec(ctx, updatePatternQuarantine, arg.EntityID, arg.Quarantined)
return err
}
const updatePatternStatus = `-- name: UpdatePatternStatus :exec
UPDATE patterns SET status = $2, version = version + 1,
last_validated_at = CASE WHEN $2 = 'validated' THEN now() ELSE last_validated_at END
WHERE entity_id = $1
`
type UpdatePatternStatusParams struct {
EntityID uuid.UUID
Status string
}
func (q *Queries) UpdatePatternStatus(ctx context.Context, arg UpdatePatternStatusParams) error {
_, err := q.db.Exec(ctx, updatePatternStatus, arg.EntityID, arg.Status)
return err
}
const updateSkillStatus = `-- name: UpdateSkillStatus :exec
UPDATE skills SET status = $2, last_used_at = now() WHERE entity_id = $1 AND version = $2
`
type UpdateSkillStatusParams struct {
EntityID uuid.UUID
Status string
}
func (q *Queries) UpdateSkillStatus(ctx context.Context, arg UpdateSkillStatusParams) error {
_, err := q.db.Exec(ctx, updateSkillStatus, arg.EntityID, arg.Status)
return err
}
const upsertEntityStatus = `-- name: UpsertEntityStatus :exec
INSERT INTO entity_status (entity_id, health, last_check_at, details)
VALUES ($1, $2, $3, $4)
ON CONFLICT (entity_id)
DO UPDATE SET health = EXCLUDED.health,
last_check_at = EXCLUDED.last_check_at,
details = EXCLUDED.details,
updated_at = now()
`
type UpsertEntityStatusParams struct {
EntityID uuid.UUID
Health string
LastCheckAt *time.Time
Details []byte
}
func (q *Queries) UpsertEntityStatus(ctx context.Context, arg UpsertEntityStatusParams) error {
_, err := q.db.Exec(ctx, upsertEntityStatus,
arg.EntityID,
arg.Health,
arg.LastCheckAt,
arg.Details,
)
return err
}
const upsertPattern = `-- name: UpsertPattern :exec
INSERT INTO patterns (entity_id, applies_type, action, pattern, confidence,
evidence_count, success_count, failure_count, status, version)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, 'hypothesized', 1)
ON CONFLICT (applies_type, action)
DO UPDATE SET evidence_count = patterns.evidence_count + EXCLUDED.evidence_count,
success_count = patterns.success_count + EXCLUDED.success_count,
failure_count = patterns.failure_count + EXCLUDED.failure_count,
updated_at = now()
`
type UpsertPatternParams struct {
EntityID uuid.UUID
AppliesType string
Action string
Pattern string
Confidence float32
EvidenceCount int32
SuccessCount int32
FailureCount int32
}
func (q *Queries) UpsertPattern(ctx context.Context, arg UpsertPatternParams) error {
_, err := q.db.Exec(ctx, upsertPattern,
arg.EntityID,
arg.AppliesType,
arg.Action,
arg.Pattern,
arg.Confidence,
arg.EvidenceCount,
arg.SuccessCount,
arg.FailureCount,
)
return err
}
const upsertSignal = `-- name: UpsertSignal :one
INSERT INTO signals (entity_id, kind, severity, target_entity_id, check_id, evidence, likely_cause, state)
VALUES ($1, $2, $3, $4, $5, $6, $7, 'raised')
ON CONFLICT (target_entity_id, kind) WHERE state NOT IN ('resolved','failed')
DO UPDATE SET occurrence_count = signals.occurrence_count + 1,
last_seen_at = now(),
evidence = EXCLUDED.evidence,
updated_at = now()
RETURNING entity_id, kind, severity, target_entity_id, check_id, evidence, likely_cause, state, occurrence_count, first_seen_at, last_seen_at, flap_count, hold_down_until, mute_until, created_at, updated_at
`
type UpsertSignalParams struct {
EntityID uuid.UUID
Kind string
Severity string
TargetEntityID *uuid.UUID
CheckID *uuid.UUID
Evidence *string
LikelyCause *string
}
func (q *Queries) UpsertSignal(ctx context.Context, arg UpsertSignalParams) (Signal, error) {
row := q.db.QueryRow(ctx, upsertSignal,
arg.EntityID,
arg.Kind,
arg.Severity,
arg.TargetEntityID,
arg.CheckID,
arg.Evidence,
arg.LikelyCause,
)
var i Signal
err := row.Scan(
&i.EntityID,
&i.Kind,
&i.Severity,
&i.TargetEntityID,
&i.CheckID,
&i.Evidence,
&i.LikelyCause,
&i.State,
&i.OccurrenceCount,
&i.FirstSeenAt,
&i.LastSeenAt,
&i.FlapCount,
&i.HoldDownUntil,
&i.MuteUntil,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const worstHealthForTarget = `-- name: WorstHealthForTarget :one
SELECT COALESCE(
(SELECT last_health FROM check_defs
WHERE enabled AND target_id = $1 AND last_health IS NOT NULL
ORDER BY CASE last_health
WHEN 'down' THEN 0 WHEN 'degraded' THEN 1 WHEN 'stale' THEN 2
WHEN 'unknown' THEN 3 ELSE 4 END
LIMIT 1),
'unknown')::text AS health
`
// An entity is as healthy as its unhealthiest check. Checks that have not run
// yet (last_health IS NULL) are ignored rather than counted as unknown, so a
// newly added check does not drag a known-good entity down before it has
// produced a verdict.
func (q *Queries) WorstHealthForTarget(ctx context.Context, targetID *uuid.UUID) (string, error) {
row := q.db.QueryRow(ctx, worstHealthForTarget, targetID)
var health string
err := row.Scan(&health)
return health, err
}