Documentation
¶
Index ¶
- Constants
- Variables
- func NormalizedTriggerPath(path string) string
- func NormalizedTriggerPathForConfiguration(triggerType TriggerType, configuration string) (string, error)
- func RoleLevel(r Role) int
- func ValidRole(r string) bool
- type APIKey
- type AgentAction
- type AgentActionActor
- type AgentActionStatus
- type AgentClaim
- type AgentProfile
- type AgentSession
- type AgentSessionState
- type ApprovalDecision
- type ApprovalRequest
- type Atom
- type AtomEngine
- type Atoms
- type AuditLog
- type Backfill
- type BackfillStatus
- type Callback
- type CallbackRun
- type CallbackRunStatus
- type CallbackRuns
- type CallbackType
- type Callbacks
- type ChannelType
- type ContractAck
- type DagSnapshot
- type DagSnapshotEdge
- type DagSnapshotTask
- type DatasetDeclaration
- type DatasetDerivation
- type DatasetState
- type EventTriggerMatch
- type ExecutionEvent
- type Incident
- type IncidentStatus
- type IngestedEvent
- type InternalCAGeneration
- type InternalNodeEnrollment
- type Job
- type JobRun
- type Jobs
- type KeyScope
- type LineageDataset
- type NotificationChannel
- type NotificationPolicy
- type RateLimitToken
- type RemediationTimer
- type RemediationTimerStatus
- type ReprocessPolicy
- type Role
- type RunCheckpoint
- type RunLease
- type RunQueue
- type SAMLAssertionReplay
- type Session
- type Task
- type TaskCache
- type TaskEdge
- type TaskEdges
- type TaskExecutionBaseline
- type TaskExecutionCache
- type TaskExecutionDAG
- type TaskExecutionDescriptor
- type TaskExecutionEdgeRef
- type TaskExecutionFanOut
- type TaskExecutionFanOutGroup
- type TaskExecutionJob
- type TaskExecutionRun
- type TaskExecutionRuntime
- type TaskExecutionSchema
- type TaskExecutionSecretRef
- type TaskExecutionTiming
- type TaskRun
- type Tasks
- type Trigger
- type TriggerType
- type Triggers
- type User
- type WebhookEvent
Constants ¶
const ( DatasetDirectionProduces = "produces" DatasetDirectionConsumes = "consumes" DatasetDirectionSource = "source" )
Dataset declaration direction values. They mirror the jobdef constants (pkg/jobdef.DatasetDirection*) and are duplicated here so the models package stays free of a jobdef import.
const ( DatasetDecisionDerived = "derived" DatasetDecisionSkippedFresh = "skipped_fresh" DatasetDecisionSkippedUpstream = "skipped_upstream" DatasetDecisionSkippedAdmission = "skipped_admission" DatasetDecisionSkippedActiveRun = "skipped_active_run" )
Dataset derivation decision values — the "why did/didn't this run" audit the leader-gated evaluator (Stream C) appends. A `derived` decision carries the resulting run id; the `skipped_*` decisions record why no run was started.
const ( DatasetStatusUnknown = "unknown" DatasetStatusFresh = "fresh" DatasetStatusStale = "stale" DatasetStatusStaleUpstream = "stale-upstream" DatasetStatusViolated = "violated" DatasetStatusQuarantined = "quarantined" )
Dataset freshness status values. The state store (internal/freshness) sets a neutral default; the leader-gated evaluator (Stream C) owns the transitions between fresh/stale/stale-upstream/violated/quarantined.
const ( JobRunStatusCancelled = "cancelled" TaskRunStatusCancelled = "cancelled" )
const DefaultTriageOnlyProfileName = "triage-only"
DefaultTriageOnlyProfileName is the shipped zero-risk default AgentProfile: tier 0 (deterministic rules only) plus escalate, so teams can adopt agent-in-the-loop remediation incrementally without granting any autonomous action. It is a built-in name: a job's metadata.remediation.profile may reference it and server-side lint/apply treats it as always resolvable even before the row is seeded, so a fresh server never rejects the advertised default. See docs/design-agent-in-the-loop.md.
const ExecutionEventTypeRunCancelled = "run_cancelled"
const TaskExecutionDescriptorSchemaVersion = 1
Variables ¶
var All = []any{ &Atom{}, &Trigger{}, &Job{}, &RunQueue{}, &IngestedEvent{}, &WebhookEvent{}, &Task{}, &TaskEdge{}, &Callback{}, &Backfill{}, &JobRun{}, &TaskRun{}, &LineageDataset{}, &ContractAck{}, &TaskCache{}, &CallbackRun{}, &ExecutionEvent{}, &EventTriggerMatch{}, &APIKey{}, &AuditLog{}, &User{}, &Session{}, &SAMLAssertionReplay{}, &NotificationChannel{}, &NotificationPolicy{}, &RateLimitToken{}, &RunLease{}, &InternalCAGeneration{}, &InternalNodeEnrollment{}, &RunCheckpoint{}, &DagSnapshot{}, &DatasetDeclaration{}, &DatasetState{}, &DatasetDerivation{}, &Incident{}, &AgentProfile{}, &AgentSession{}, &AgentAction{}, &ApprovalRequest{}, &RemediationTimer{}, }
All lists every model for AutoMigrate. Order matters: parent tables must appear before children so that foreign-key constraints can reference them.
Functions ¶
func NormalizedTriggerPath ¶
func NormalizedTriggerPathForConfiguration ¶
func NormalizedTriggerPathForConfiguration(triggerType TriggerType, configuration string) (string, error)
Types ¶
type APIKey ¶
type APIKey struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
KeyPrefix string `gorm:"type:text;size:12;not null;index" json:"key_prefix"`
KeyHash string `gorm:"type:text;not null;uniqueIndex" json:"-"`
BootstrapSlot *string `gorm:"type:text;uniqueIndex" json:"-"`
Description string `gorm:"type:text" json:"description,omitempty"`
Role Role `gorm:"type:text;not null" json:"role"`
Scope datatypes.JSON `gorm:"type:json" json:"scope,omitempty"`
CreatedBy string `gorm:"type:text" json:"created_by,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
}
APIKey represents an API key stored in the database. The plaintext key is never persisted — only a versioned stored hash.
type AgentAction ¶
type AgentAction struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Namespace is nullable from day one (design Open Question 4).
Namespace *string `gorm:"type:text;index" json:"namespace,omitempty"`
// IncidentID is non-nullable — the audit spine always ties to an incident.
IncidentID uuid.UUID `gorm:"type:uuid;index;not null" json:"incident_id"`
Incident Incident `gorm:"constraint:OnDelete:CASCADE" json:"-"`
// SessionID is nullable: policy/human rows have no agent session.
SessionID *uuid.UUID `gorm:"type:uuid;index" json:"session_id,omitempty"`
Session *AgentSession `gorm:"constraint:OnDelete:SET NULL" json:"-"`
Type string `gorm:"type:text;index;not null" json:"type"`
Params datatypes.JSON `gorm:"type:json" json:"params,omitempty"`
Tier int `gorm:"not null;default:0" json:"tier"`
Status AgentActionStatus `gorm:"type:text;index;not null" json:"status"`
Result datatypes.JSON `gorm:"type:json" json:"result,omitempty"`
Actor AgentActionActor `gorm:"type:text;index;not null" json:"actor"`
CreatedAt time.Time `gorm:"not null;index" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
AgentAction is the audit spine: every remediation attempt (whether taken by a deterministic policy rule, the container agent, or a human) is recorded as a row. The incident reference is NON-NULLABLE so the timeline reconstructs for actor=policy|human rows that have no session; the session reference is nullable. Append-only, low-volume.
type AgentActionActor ¶
type AgentActionActor string
AgentActionActor identifies who originated an action row.
const ( // ActorPolicy is a deterministic server-side rule (Phase 0) — no container. AgentActionActorPolicy AgentActionActor = "policy" // ActorAgent is the container-native agent (Phase 1+). AgentActionActorAgent AgentActionActor = "agent" // ActorHuman is an operator action. AgentActionActorHuman AgentActionActor = "human" )
type AgentActionStatus ¶
type AgentActionStatus string
AgentActionStatus enumerates an action's lifecycle in the audit spine.
const ( AgentActionStatusProposed AgentActionStatus = "proposed" AgentActionStatusApproved AgentActionStatus = "approved" AgentActionStatusRejected AgentActionStatus = "rejected" // AgentActionStatusExecuting is the CLAIM an approved action holds while it // is being dispatched. It exists so dispatch is once-only: the executor moves // approved → executing with a conditional UPDATE, and a second attempt (the // redrive sweeper racing the synchronous post-decision execute, or two // operators' requests interleaving) matches zero rows and does nothing. // // A row left `executing` by a process death is a deliberately VISIBLE stuck // state, not an invisible one: it is never auto-redriven, because re-running a // half-applied tier-3 mutation (a jobdef patch, a skipped task) unattended is // worse than surfacing it for a human. See ApprovalRedriver. AgentActionStatusExecuting AgentActionStatus = "executing" AgentActionStatusExecuted AgentActionStatus = "executed" AgentActionStatusFailed AgentActionStatus = "failed" )
type AgentClaim ¶
type AgentClaim struct {
// IncidentID is the only incident whose /v1/agent/* routes this key may call.
IncidentID uuid.UUID `json:"incident_id"`
// Jobs is the frozen job allowlist governing which jobs' read-only context
// (logs, why, run history) the agent may pull through the context routes.
Jobs []string `json:"jobs,omitempty"`
}
AgentClaim binds an API key to a single incident's agent tool surface. It is minted by the incident manager (an unscoped, server-side principal) for one agent session and expires with that session. The read scope is FROZEN at incident open: Jobs is the static job allowlist the incident manager snapshotted from the lineage-impact graph (excluding edges derived from the failing run's own outputs). The agent cannot widen it — server-side enforcement is the boundary, not the prompt.
type AgentProfile ¶
type AgentProfile struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Namespace is nullable from day one (design Open Question 4).
Namespace *string `gorm:"type:text;index" json:"namespace,omitempty"`
Name string `gorm:"uniqueIndex;not null" json:"name"`
Image string `gorm:"type:text;not null" json:"image"`
Engine AtomEngine `gorm:"type:text;not null;default:'docker'" json:"engine"`
// Limits holds resource limits (cpu/memory/wall-clock) as JSON.
Limits datatypes.JSON `gorm:"type:json" json:"limits,omitempty"`
// SecretRefs holds secret:// references (e.g. the model API key) as JSON.
// Never resolved values — only the references.
SecretRefs datatypes.JSON `gorm:"type:json" json:"secret_refs,omitempty"`
// Budgets holds per-session budget defaults (max actions, token/cost caps).
Budgets datatypes.JSON `gorm:"type:json" json:"budgets,omitempty"`
// Playbook holds the default action-catalog policy for jobs using this profile.
Playbook datatypes.JSON `gorm:"type:json" json:"playbook,omitempty"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
AgentProfile is the server-side resource declaring how a remediation agent runs: its container image/engine, resource limits, model-credential secret:// references, session budgets, and the default playbook. It is referenced by a job's metadata.remediation block. Low-volume catalog row.
type AgentSession ¶
type AgentSession struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Namespace is nullable from day one (design Open Question 4).
Namespace *string `gorm:"type:text;index" json:"namespace,omitempty"`
IncidentID uuid.UUID `gorm:"type:uuid;index;not null" json:"incident_id"`
Incident Incident `gorm:"constraint:OnDelete:CASCADE" json:"-"`
ProfileID *uuid.UUID `gorm:"type:uuid;index" json:"profile_id,omitempty"`
Profile *AgentProfile `gorm:"constraint:OnDelete:SET NULL" json:"-"`
Engine AtomEngine `gorm:"type:text" json:"engine,omitempty"`
// AtomID / ContainerID identify the launched container/atom for the UI and
// for stop/cleanup.
AtomID *uuid.UUID `gorm:"type:uuid;index" json:"atom_id,omitempty"`
ContainerID string `gorm:"type:text" json:"container_id,omitempty"`
// TokenID is the scoped, short-lived agent credential bound to this session.
TokenID *uuid.UUID `gorm:"type:uuid;index" json:"token_id,omitempty"`
State AgentSessionState `gorm:"type:text;index;not null;default:'pending'" json:"state"`
// SessionLog is the persisted agent-container log for the UI timeline.
SessionLog string `gorm:"type:text" json:"session_log,omitempty"`
// Budget counters. These are best-effort accounting the executor increments.
ActionsUsed int `gorm:"not null;default:0" json:"actions_used"`
TokensUsed int `gorm:"not null;default:0" json:"tokens_used"`
StartedAt *time.Time `json:"started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
// Extra carries additional session metadata (e.g. frozen allowlist) as JSON.
Extra datatypes.JSON `gorm:"type:json" json:"extra,omitempty"`
}
AgentSession records a single agent container run launched through the existing atom.Engine to triage an incident. It is DELIBERATELY NOT a JobRun / TaskRun: a session materialized as a run would pollute the quarantine-filtered run statistics and feed its own exhaust back into the incident bus. Low-volume.
type AgentSessionState ¶
type AgentSessionState string
AgentSessionState enumerates the terminal-tracked lifecycle of an agent container session.
const ( AgentSessionStatePending AgentSessionState = "pending" AgentSessionStateRunning AgentSessionState = "running" AgentSessionStateSucceeded AgentSessionState = "succeeded" AgentSessionStateFailed AgentSessionState = "failed" AgentSessionStateTimedOut AgentSessionState = "timed_out" AgentSessionStateCancelled AgentSessionState = "cancelled" )
type ApprovalDecision ¶
type ApprovalDecision string
ApprovalDecision enumerates the outcome of a tier-3 approval request.
const ( ApprovalDecisionPending ApprovalDecision = "pending" ApprovalDecisionApproved ApprovalDecision = "approved" ApprovalDecisionRejected ApprovalDecision = "rejected" ApprovalDecisionExpired ApprovalDecision = "expired" )
type ApprovalRequest ¶
type ApprovalRequest struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Namespace is nullable from day one (design Open Question 4).
Namespace *string `gorm:"type:text;index" json:"namespace,omitempty"`
// IncidentID lets the operator read API filter approvals by incident without
// a join through the action.
IncidentID uuid.UUID `gorm:"type:uuid;index;not null" json:"incident_id"`
ActionID uuid.UUID `gorm:"type:uuid;index;not null" json:"action_id"`
Action AgentAction `gorm:"constraint:OnDelete:CASCADE" json:"-"`
// ApproversHint is a free-text hint for who should decide (role/channel).
ApproversHint string `gorm:"type:text" json:"approvers_hint,omitempty"`
Decision ApprovalDecision `gorm:"type:text;index;not null;default:'pending'" json:"decision"`
// Decider records the operator identity that resolved the request.
Decider string `gorm:"type:text" json:"decider,omitempty"`
Reason string `gorm:"type:text" json:"reason,omitempty"`
ExpiresAt *time.Time `gorm:"index" json:"expires_at,omitempty"`
DecidedAt *time.Time `json:"decided_at,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
ApprovalRequest is created by every tier-3 action and resolved by a human operator. Tier-3 actions are NEVER auto-executed regardless of config, so an approval always terminates at a human decision. Low-volume catalog row.
type Atom ¶
type Atom struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Engine AtomEngine `gorm:"index;not null" json:"engine"`
Image string `gorm:"index;not null" json:"image"`
Command string `gorm:"command" json:"command"`
Spec datatypes.JSON `gorm:"type:jsonb" json:"spec"`
ReplaySafe bool `gorm:"not null;default:false" json:"replay_safe"`
ProvenanceSourceID string `gorm:"index" json:"provenance_source_id"`
ProvenanceRepo string `json:"provenance_repo"`
ProvenanceRef string `json:"provenance_ref"`
ProvenanceCommit string `json:"provenance_commit"`
ProvenancePath string `json:"provenance_path"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
func (*Atom) ContainerSpec ¶
type AtomEngine ¶
type AtomEngine string
const ( AtomEngineDocker AtomEngine = "docker" AtomEngineKubernetes AtomEngine = "kubernetes" AtomEnginePodman AtomEngine = "podman" )
type AuditLog ¶
type AuditLog struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Timestamp time.Time `gorm:"not null;index" json:"timestamp"`
Actor string `gorm:"type:text;not null;index" json:"actor"`
Action string `gorm:"type:text;not null;index" json:"action"`
ResourceType string `gorm:"type:text" json:"resource_type,omitempty"`
ResourceID string `gorm:"type:text" json:"resource_id,omitempty"`
SourceIP string `gorm:"type:text" json:"source_ip,omitempty"`
Outcome string `gorm:"type:text;not null" json:"outcome"`
Metadata datatypes.JSON `gorm:"type:json" json:"metadata,omitempty"`
}
AuditLog records every state-changing operation and auth rejection.
type Backfill ¶
type Backfill struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
JobID uuid.UUID `gorm:"type:uuid;index;not null" json:"job_id"`
Job Job `gorm:"constraint:OnDelete:CASCADE" json:"-"`
Status string `gorm:"type:text;not null" json:"status"`
Start time.Time `gorm:"not null" json:"start"`
End time.Time `gorm:"not null" json:"end"`
MaxConcurrent int `gorm:"not null;default:1" json:"max_concurrent"`
Reprocess string `gorm:"type:text;not null" json:"reprocess"`
TotalRuns int `gorm:"not null;default:0" json:"total_runs"`
CompletedRuns int `gorm:"not null;default:0" json:"completed_runs"`
FailedRuns int `gorm:"not null;default:0" json:"failed_runs"`
CancelRequestedAt *time.Time `json:"cancel_requested_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
type BackfillStatus ¶
type BackfillStatus string
const ( BackfillStatusRunning BackfillStatus = "running" BackfillStatusSucceeded BackfillStatus = "succeeded" BackfillStatusFailed BackfillStatus = "failed" BackfillStatusCancelled BackfillStatus = "cancelled" )
type Callback ¶
type Callback struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey"`
Type CallbackType `gorm:"index;type:string;not null"`
Configuration string `gorm:"not null"`
JobID uuid.UUID `gorm:"index;not null"`
Job Job `gorm:"constraint:OnDelete:CASCADE" json:"-"`
Position int `gorm:"not null;default:0" json:"-"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null"`
UpdatedAt time.Time `gorm:"not null"`
}
type CallbackRun ¶
type CallbackRun struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey"`
CallbackID uuid.UUID `gorm:"type:uuid;index;not null"`
Callback Callback `gorm:"constraint:OnDelete:CASCADE" json:"-"`
JobID uuid.UUID `gorm:"type:uuid;index;not null"`
JobRunID uuid.UUID `gorm:"type:uuid;index;not null"`
JobRun JobRun `gorm:"constraint:OnDelete:CASCADE" json:"-"`
Status CallbackRunStatus `gorm:"type:text;index;not null"`
Error string `gorm:"type:text"`
StartedAt time.Time `gorm:"not null"`
CompletedAt *time.Time
CreatedAt time.Time `gorm:"not null"`
UpdatedAt time.Time `gorm:"not null"`
}
type CallbackRunStatus ¶
type CallbackRunStatus string
const ( CallbackRunStatusPending CallbackRunStatus = "pending" CallbackRunStatusRunning CallbackRunStatus = "running" CallbackRunStatusSucceeded CallbackRunStatus = "succeeded" CallbackRunStatusFailed CallbackRunStatus = "failed" )
type CallbackRuns ¶
type CallbackRuns []*CallbackRun
type CallbackType ¶
type CallbackType string
const (
CallbackTypeNotification CallbackType = "notification"
)
type ChannelType ¶
type ChannelType string
ChannelType identifies the notification transport.
const ( ChannelTypeWebhook ChannelType = "webhook" ChannelTypeSlack ChannelType = "slack" ChannelTypeEmail ChannelType = "email" ChannelTypePagerDuty ChannelType = "pagerduty" ChannelTypeAIAgent ChannelType = "ai_agent" )
type ContractAck ¶
type ContractAck struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Dataset is the human-readable contract subject: an OpenLineage dataset
// identity when present, otherwise the producer output-key subject for an
// inferred event-trigger edge.
Dataset string `gorm:"type:text;not null;index:idx_contract_ack_dataset_digest,priority:1" json:"dataset"`
// EdgeSetDigest is a deterministic digest over the breaking edge set the
// ack covers. C2's --allow-breaking path writes this exact value.
EdgeSetDigest string `gorm:"type:text;not null;index:idx_contract_ack_dataset_digest,priority:2;index" json:"edge_set_digest"`
Actor string `gorm:"type:text;not null;default:''" json:"actor"`
Reason string `gorm:"type:text;not null;default:''" json:"reason"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
ExpiresAt time.Time `gorm:"not null;index" json:"expires_at"`
}
ContractAck records an intentional, time-bounded acknowledgement of a breaking contract edge set. It is a low-volume catalog table; run hot paths must not depend on it.
type DagSnapshot ¶
type DagSnapshot struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// JobID links this snapshot to its job. Rows are cascade-deleted when the
// job is hard-deleted; soft-deleted jobs retain their snapshots.
// Part of the composite dedup index (job_id, content_hash) and the
// query-by-recency index (job_id, created_at).
JobID uuid.UUID `gorm:"type:uuid;not null;index:idx_dag_snapshot_job_hash;index:idx_dag_snapshot_job_created" json:"job_id"`
Job Job `gorm:"constraint:OnDelete:CASCADE" json:"-"`
// ContentHash is a SHA-256 hex digest of the canonical topology (sorted
// task names each with image+command, plus sorted from→to edge pairs).
// It is the dedup key: if the most-recent snapshot for this job already
// carries this hash, no new row is written.
ContentHash string `gorm:"type:text;not null;index:idx_dag_snapshot_job_hash" json:"content_hash"`
// GitCommit is the provenance commit SHA at apply time (empty when the
// apply carries no provenance). Together with ContentHash it lets callers
// identify "when did this topology first appear and from which commit."
GitCommit string `gorm:"type:text;not null;default:''" json:"git_commit"`
// Tasks is a JSON array of task descriptors (name, image, command) captured
// at snapshot time. It is informational — the live task_runs rows remain
// authoritative for execution.
Tasks datatypes.JSON `gorm:"type:json;not null" json:"tasks"`
// Edges is a JSON array of edge descriptors ({from, to, provenance_commit})
// captured at snapshot time.
Edges datatypes.JSON `gorm:"type:json;not null" json:"edges"`
// CreatedAt is the wall-clock time the snapshot was written (append-only;
// rows are never updated). Part of the idx_dag_snapshot_job_created index
// so the dedup query (ORDER BY created_at DESC LIMIT 1) uses the index.
CreatedAt time.Time `gorm:"not null;index:idx_dag_snapshot_job_created" json:"created_at"`
}
DagSnapshot is an append-only record of a job's full topology (tasks + edges) at a point in time. One row is written per apply when the topology changes; unchanged topology reuses the existing row (dedup by ContentHash).
This is the persistence layer for Component 3 (Version DAG topology) from docs/design-data-plane-memory.md. The live graph in task_edges still drives execution; dag_snapshots preserves history so "the pipeline as of commit X" is reconstructable from dqlite without a git checkout.
type DagSnapshotEdge ¶
type DagSnapshotEdge struct {
From string `json:"from"`
To string `json:"to"`
ProvenanceCommit string `json:"provenance_commit,omitempty"`
}
DagSnapshotEdge is the per-edge descriptor stored inside DagSnapshot.Edges.
type DagSnapshotTask ¶
type DagSnapshotTask struct {
Name string `json:"name"`
Image string `json:"image"`
Command []string `json:"command,omitempty"`
}
DagSnapshotTask is the per-task descriptor stored inside DagSnapshot.Tasks. Command is stored as a slice (not space-joined) to preserve argument boundaries.
type DatasetDeclaration ¶
type DatasetDeclaration struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// JobID links this declaration to its job. Rows are cascade-deleted when the
// job is hard-deleted; the importer also rebuilds a job's declarations on
// every apply and prunes them when the job is retired.
JobID uuid.UUID `gorm:"type:uuid;not null;index:idx_dataset_decl_job" json:"job_id"`
Job Job `gorm:"constraint:OnDelete:CASCADE" json:"-"`
// JobAlias is denormalized so the cross-job lint can resolve producers and
// build the derivation graph without joining back to jobs.
JobAlias string `gorm:"type:text;not null;index:idx_dataset_decl_alias" json:"job_alias"`
// StepName is the producing/consuming step. It is empty for a
// metadata-level source declaration (direction=source).
StepName string `gorm:"type:text;not null;default:''" json:"step_name"`
// Namespace is nullable (reserved for cross-instance datasets, unused in v1).
// Name is the dataset identity the whole feature keys on.
Namespace *string `gorm:"type:text;index:idx_dataset_decl_identity,priority:1" json:"namespace,omitempty"`
Name string `gorm:"type:text;not null;index:idx_dataset_decl_identity,priority:2" json:"name"`
// Direction is one of DatasetDirectionProduces / Consumes / Source.
Direction string `gorm:"type:text;not null;index:idx_dataset_decl_identity,priority:3" json:"direction"`
// Freshness / MaxStaleness are the produced dataset's SLO (Go duration
// strings). ExpectedEvery is the source dataset's cadence expectation. All
// empty when not applicable to the direction.
Freshness string `gorm:"type:text;not null;default:''" json:"freshness,omitempty"`
MaxStaleness string `gorm:"type:text;not null;default:''" json:"max_staleness,omitempty"`
ExpectedEvery string `gorm:"type:text;not null;default:''" json:"expected_every,omitempty"`
// WatermarkKey is the ##caesium::output key a producing step emits to
// advance the dataset. Empty in degraded mode (no declared watermark).
WatermarkKey string `gorm:"type:text;not null;default:''" json:"watermark_key,omitempty"`
// SchemaJSON is the marshaled inline JSON Schema declared on
// produces[].schema or consumes[].schema. Empty when no inline schema was
// declared.
SchemaJSON string `gorm:"type:text" json:"schema_json,omitempty"`
// SchemaFrom is the producing step-local schema source (currently "output").
// Empty for consumed declarations and produced declarations without
// schemaFrom.
SchemaFrom string `gorm:"type:text" json:"schema_from,omitempty"`
// SchemaVersion carries produces[].version for intentional dataset contract
// breaks. It is zero when unset and unused for consumed/source declarations.
SchemaVersion int `json:"schema_version,omitempty"`
// SkipWhenFresh carries metadata.datasets.skipWhenFresh after defaulting.
// It is evaluated at the cron scheduling seam only and never affects a task's
// cache identity. Pointer form preserves an explicit false across GORM's
// default:true create path.
SkipWhenFresh *bool `gorm:"not null;default:true" json:"skip_when_fresh,omitempty"`
// External marks a source dataset nobody in Caesium produces.
External bool `gorm:"not null;default:false" json:"external"`
// ArrivalBinding is the source dataset's arrival event pattern + watermark
// JSONPath, stored as JSON. Empty for produced/consumed declarations.
ArrivalBinding datatypes.JSON `gorm:"type:json" json:"arrival_binding,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
DatasetDeclaration is the persisted *declared* dataset graph — the complement to the *observed* LineageDataset graph (which requires OpenLineage). One row is written per (job, step, dataset, direction) relationship declared in a job's `datasets` surface, rebuilt from the manifest on every apply so a removed declaration is pruned. It stores only scheduling metadata (SLOs, watermark key, arrival binding); it never enters the cache identity and is not a hot per-run table.
Dataset identity is keyed on Name in v1. Namespace is nullable and carried from day one (per the design's Non-goals) so cross-instance namespacing can be added later without a migration rewrite; it is not populated in v1.
type DatasetDerivation ¶
type DatasetDerivation struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Namespace is nullable (unused in v1); Name is the dataset identity.
Namespace *string `gorm:"type:text;index:idx_dataset_deriv_identity,priority:1" json:"namespace,omitempty"`
Name string `gorm:"type:text;not null;index:idx_dataset_deriv_identity,priority:2" json:"name"`
// Decision is one of DatasetDecision* above.
Decision string `gorm:"type:text;not null" json:"decision"`
// Reason is a human-readable elaboration of the decision (e.g. "fresh
// (2h/6h)", "waiting on raw.vendor_x"). Empty when the decision is
// self-explanatory.
Reason string `gorm:"type:text;not null;default:''" json:"reason,omitempty"`
// ConsumedWatermarks snapshots the consumed dataset watermarks the decision
// evaluated against, as a JSON object keyed by consumed dataset name.
ConsumedWatermarks datatypes.JSON `gorm:"type:json" json:"consumed_watermarks,omitempty"`
// RunID is the derived run for a `derived` decision; nil for a skip. A soft
// reference (no FK) so run pruning never cascades into the audit trail.
RunID *uuid.UUID `gorm:"type:uuid;index" json:"run_id,omitempty"`
// CreatedAt is the decision time (append-only; rows are never updated).
CreatedAt time.Time `gorm:"not null;index:idx_dataset_deriv_created" json:"created_at"`
}
DatasetDerivation is the append-only audit of every evaluator decision for a dataset: whether it derived a run, and if not, why. It is the row behind the "why did/didn't this run" operator surface. Never updated — one row per decision. Not a hot per-run table.
The consumed-watermark snapshot records what the decision saw for the dataset's inputs, so a later reader can reconstruct the derivation without re-deriving state. RunID is the resulting run for a `derived` decision and nil for a skip.
type DatasetState ¶
type DatasetState struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Namespace is reserved for cross-instance datasets (unused in v1) and Name
// is the dataset identity the whole feature keys on. Together they are the
// natural key, enforced by a real UNIQUE index — Namespace is NOT NULL with a
// ” default (rather than nullable) precisely so the unique index is reliable
// under SQLite, which treats NULLs as distinct in a UNIQUE index and would
// otherwise let two rows share one dataset identity. The store maps a nil
// namespace to ” on every query.
Namespace string `gorm:"type:text;not null;default:'';uniqueIndex:idx_dataset_state_identity,priority:1" json:"namespace,omitempty"`
Name string `gorm:"type:text;not null;uniqueIndex:idx_dataset_state_identity,priority:2" json:"name"`
// Watermark is the current high-water value emitted by the producing step
// (or an arrival binding). Empty until the dataset first advances.
Watermark string `gorm:"type:text;not null;default:''" json:"watermark"`
// WatermarkRunAt orders the run that set the current Watermark. It gates
// opaque-string watermarks (git SHAs/UUIDs have no orderable relation): a
// later-finishing older run must not clobber a newer value, so an opaque
// write only overwrites when the incoming run is newer than this. Nullable
// until the first advance.
WatermarkRunAt *time.Time `json:"watermark_run_at,omitempty"`
// AdvancedAt is the time the watermark last CHANGED (increased, for
// orderable values). VerifiedAt is the time a successful run last CONFIRMED
// the current watermark without changing it. Both nullable until observed.
AdvancedAt *time.Time `json:"advanced_at,omitempty"`
VerifiedAt *time.Time `json:"verified_at,omitempty"`
// Status / Reason are owned by the evaluator (Stream C). The state store
// leaves them at their defaults.
Status string `gorm:"type:text;not null;default:'unknown'" json:"status"`
Reason string `gorm:"type:text;not null;default:''" json:"reason,omitempty"`
// LastRunID is the run that most recently advanced or verified this dataset.
// It is a soft reference (no FK constraint) so run pruning never cascades
// into dataset state.
LastRunID *uuid.UUID `gorm:"type:uuid;index" json:"last_run_id,omitempty"`
// ConsumedWatermarks snapshots the watermarks of this dataset's declared
// inputs as LastRunID STARTED — the view that run actually consumed, not the
// values current when it finished — so "is my output up to date with my
// inputs" is a pure row comparison, not a heuristic. JSON object keyed by
// consumed dataset name. See internal/freshness.Capturer.consumedForRun for
// the three sources of that start-time view.
ConsumedWatermarks datatypes.JSON `gorm:"type:json" json:"consumed_watermarks,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
DatasetState is the durable truth every scheduling decision reads: one row per dataset (natural key namespace+name). It distinguishes "a run succeeded" from "the output advanced" — Watermark/AdvancedAt move only on a real watermark change (see internal/freshness.Store.Advance), while VerifiedAt records a successful run that merely confirmed the current value. Freshness is evaluated against max(AdvancedAt, VerifiedAt).
Namespace is nullable and unused in v1 (mirrors DatasetDeclaration); dataset identity keys on Name today. This is NOT a hot per-run table: it is written at run completion and by the evaluator, not on the per-task hot path.
type EventTriggerMatch ¶
type EventTriggerMatch struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
EventID uuid.UUID `gorm:"type:uuid;index;not null" json:"event_id"`
Event IngestedEvent `gorm:"constraint:OnDelete:CASCADE" json:"-"`
TriggerID uuid.UUID `gorm:"type:uuid;index;not null" json:"trigger_id"`
MatchedAt time.Time `gorm:"not null;index" json:"matched_at"`
RunsStarted datatypes.JSON `gorm:"type:json" json:"runs_started,omitempty"`
Skipped bool `gorm:"not null;default:false" json:"skipped"`
SkipReason string `gorm:"type:text" json:"skip_reason,omitempty"`
Error string `gorm:"type:text" json:"error,omitempty"`
}
type ExecutionEvent ¶
type ExecutionEvent struct {
Sequence uint64 `gorm:"primaryKey;autoIncrement" json:"sequence"`
Type string `gorm:"type:text;index;not null" json:"type"`
JobID *uuid.UUID `gorm:"type:uuid;index" json:"job_id,omitempty"`
RunID *uuid.UUID `gorm:"type:uuid;index" json:"run_id,omitempty"`
TaskID *uuid.UUID `gorm:"type:uuid;index" json:"task_id,omitempty"`
Payload []byte `gorm:"type:json" json:"payload,omitempty"`
Quarantine bool `gorm:"not null;default:false;index" json:"quarantine"`
BusDispatchPending bool `gorm:"not null;default:false;index" json:"bus_dispatch_pending"`
BusDispatchedAt *time.Time `gorm:"index" json:"bus_dispatched_at,omitempty"`
CreatedAt time.Time `gorm:"not null;index" json:"created_at"`
}
type Incident ¶
type Incident struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Namespace is nullable from day one (design Open Question 4). Empty/NULL
// means the default namespace; a value scopes the incident to a tenant.
Namespace *string `gorm:"type:text;index" json:"namespace,omitempty"`
JobID uuid.UUID `gorm:"type:uuid;index;not null" json:"job_id"`
RunID *uuid.UUID `gorm:"type:uuid;index" json:"run_id,omitempty"`
TaskID *uuid.UUID `gorm:"type:uuid;index" json:"task_id,omitempty"`
TaskName string `gorm:"type:text" json:"task_name,omitempty"`
// Class is the deterministic failure_class the classifier assigned.
Class string `gorm:"type:text;index;not null" json:"class"`
// Status is the current position in the incident status machine.
Status IncidentStatus `gorm:"type:text;index;not null" json:"status"`
// DedupeKey is the stable correlation key (job_id, task_name, failure_class).
// It is recorded on every incident (open or closed) for history and querying.
DedupeKey string `gorm:"type:text;index;not null" json:"dedupe_key"`
// ActiveDedupeKey enforces "at most one non-terminal incident per dedupe key":
// it holds DedupeKey while the incident is open and is set NULL on any terminal
// transition. The unique index only constrains non-NULL rows (dqlite/SQLite
// semantics), so closed incidents never collide — mirroring the nullable
// unique-index pattern used by JobRun.ReplayFingerprint. Incident-open is an
// atomic conditional insert on this column.
ActiveDedupeKey *string `gorm:"type:text;uniqueIndex:idx_incidents_active_dedupe" json:"-"`
// OccurrenceCount counts distinct failures folded into this incident (the
// first open is occurrence 1; an independent same-key failure appends one).
OccurrenceCount int `gorm:"not null;default:1" json:"occurrence_count"`
// Attempt counts remediation attempts taken against this incident.
Attempt int `gorm:"not null;default:0" json:"attempt"`
// BackfillID storm-controls backfill-originated failures so a single backfill
// does not open one incident per spawned run.
BackfillID *uuid.UUID `gorm:"type:uuid;index" json:"backfill_id,omitempty"`
// RemediationTargetRunID is the run whose success closes the incident as
// remediated. It advances when a new occurrence folds in.
RemediationTargetRunID *uuid.UUID `gorm:"type:uuid" json:"remediation_target_run_id,omitempty"`
// AllowedJobs is the FROZEN job allowlist that scopes the agent's read
// surface for this incident, computed by the incident manager (an unscoped
// server principal) from the lineage-impact graph at open time — excluding
// edges derived from the failing run's own outputs so attacker-crafted
// ##caesium::output refs cannot widen it. It is a JSON array of job aliases.
// The agent's scoped token carries a copy; this column is the durable source
// of truth the session supervisor mints from and the bundle reports.
AllowedJobs datatypes.JSON `gorm:"type:json" json:"allowed_jobs,omitempty"`
// LastError is the failing task's error text captured at open, for the feed.
LastError string `gorm:"type:text" json:"last_error,omitempty"`
// ResolutionSummary is a short human/agent summary written at close.
ResolutionSummary string `gorm:"type:text" json:"resolution_summary,omitempty"`
// Evidence carries classifier evidence (exit code, matched rule) as JSON.
Evidence datatypes.JSON `gorm:"type:json" json:"evidence,omitempty"`
OpenedAt time.Time `gorm:"not null;index" json:"opened_at"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
Incident records a classified failure that Caesium's incident manager opened from the event bus. Incidents are append-mostly, low-volume catalog rows — NOT a hot per-run table — so they are not listed in hotPathModels().
type IncidentStatus ¶
type IncidentStatus string
IncidentStatus enumerates the states of the incident status machine (design-agent-in-the-loop.md, Phase 0). The lifecycle is:
open → triaging → (awaiting_approval ↔ triaging) → remediated | escalated → closed
with suppressed and abandoned as additional terminal dispositions.
const ( IncidentStatusOpen IncidentStatus = "open" IncidentStatusTriaging IncidentStatus = "triaging" IncidentStatusAwaitingApproval IncidentStatus = "awaiting_approval" IncidentStatusRemediated IncidentStatus = "remediated" IncidentStatusEscalated IncidentStatus = "escalated" IncidentStatusClosed IncidentStatus = "closed" IncidentStatusSuppressed IncidentStatus = "suppressed" IncidentStatusAbandoned IncidentStatus = "abandoned" )
func (IncidentStatus) IsTerminal ¶
func (s IncidentStatus) IsTerminal() bool
IsTerminal reports whether the status is a terminal incident disposition.
type IngestedEvent ¶
type IngestedEvent struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Type string `gorm:"type:text;index;not null" json:"type"`
Source string `gorm:"type:text;index" json:"source,omitempty"`
Data datatypes.JSON `gorm:"type:json" json:"data,omitempty"`
CreatedAt time.Time `gorm:"not null;index" json:"created_at"`
}
type InternalCAGeneration ¶
type InternalCAGeneration struct {
Generation int `gorm:"primaryKey" json:"generation"`
CertPEM string `gorm:"type:text;not null" json:"cert_pem"`
KeyCiphertext []byte `gorm:"type:blob;not null" json:"key_ciphertext"`
KeyNonce []byte `gorm:"type:blob;not null" json:"key_nonce"`
NotBefore time.Time `gorm:"not null;index" json:"not_before"`
NotAfter time.Time `gorm:"not null;index" json:"not_after"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
}
InternalCAGeneration stores one internal mTLS CA generation. The certificate is public; the private key is AES-GCM sealed by the dispatch/pki package.
type InternalNodeEnrollment ¶
type InternalNodeEnrollment struct {
ID string `gorm:"type:text;primaryKey" json:"id"`
NodeID string `gorm:"type:text;not null;index" json:"node_id"`
CSRPEM string `gorm:"type:text;not null" json:"csr_pem"`
CSRMac []byte `gorm:"type:blob;not null" json:"csr_mac"`
CAGeneration int `gorm:"not null;index" json:"ca_generation"`
CertPEM *string `gorm:"type:text" json:"cert_pem,omitempty"`
Status string `gorm:"type:text;not null;index" json:"status"`
RequestedAt time.Time `gorm:"not null;index" json:"requested_at"`
SignedAt *time.Time `json:"signed_at,omitempty"`
}
InternalNodeEnrollment is the catalog rendezvous for a node CSR and the leader-signed certificate produced from it.
type Job ¶
type Job struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Alias string `gorm:"uniqueIndex" json:"alias"`
TriggerID uuid.UUID `gorm:"type:uuid;index;not null" json:"trigger_id"`
Trigger Trigger `gorm:"constraint:OnDelete:CASCADE" json:"-"`
Labels datatypes.JSONMap `gorm:"type:json" json:"labels"`
Annotations datatypes.JSONMap `gorm:"type:json" json:"annotations"`
ProvenanceSourceID string `gorm:"index" json:"provenance_source_id"`
ProvenanceRepo string `json:"provenance_repo"`
ProvenanceRef string `json:"provenance_ref"`
ProvenanceCommit string `json:"provenance_commit"`
ProvenancePath string `json:"provenance_path"`
MaxParallelTasks int `json:"max_parallel_tasks"`
TaskTimeout time.Duration `json:"task_timeout"`
RunTimeout time.Duration `json:"run_timeout"`
Priority string `gorm:"type:text;not null;default:''" json:"priority,omitempty"`
Concurrency datatypes.JSON `gorm:"type:json" json:"concurrency,omitempty"`
RateLimits datatypes.JSON `gorm:"type:json" json:"rate_limits,omitempty"`
SLA datatypes.JSON `gorm:"type:json" json:"sla,omitempty"`
// SchemaValidation controls runtime output schema validation for this job's tasks.
// Values: "" (disabled), "warn" (log violations), "fail" (fail task on violation).
SchemaValidation string `gorm:"type:text;not null;default:''" json:"schema_validation,omitempty"`
ReplaySafe bool `gorm:"not null;default:false" json:"replay_safe"`
CacheConfig datatypes.JSON `gorm:"type:json" json:"cache_config,omitempty"`
// Remediation persists the job's `metadata.remediation` block verbatim (see
// pkg/jobdef.MetadataRemediation). It is what makes a job's agent policy
// ENFORCEABLE rather than merely lintable: the action executor resolves the
// effective playbook from this column, so a job that narrows what the agent
// may do autonomously is evaluated under its own policy instead of the
// deployment-wide default profile. Empty means "the job declared no policy".
Remediation datatypes.JSON `gorm:"type:json" json:"remediation,omitempty"`
Paused bool `gorm:"not null;default:false" json:"paused"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
LatestRun *JobRun `gorm:"-" json:"latest_run,omitempty"`
}
type JobRun ¶
type JobRun struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
JobID uuid.UUID `gorm:"type:uuid;index;not null" json:"job_id"`
Job Job `gorm:"constraint:OnDelete:CASCADE" json:"-"`
BackfillID *uuid.UUID `gorm:"type:uuid;index" json:"backfill_id,omitempty"`
Backfill *Backfill `gorm:"constraint:OnDelete:SET NULL" json:"-"`
TriggerID uuid.UUID `gorm:"type:uuid;index" json:"trigger_id"`
TriggerType string `gorm:"type:text" json:"trigger_type"`
TriggerAlias string `gorm:"type:text" json:"trigger_alias"`
Status string `gorm:"type:text;index;not null" json:"status"`
Priority int `gorm:"not null;default:2" json:"priority"`
Error string `json:"error,omitempty"`
Params datatypes.JSON `gorm:"type:json" json:"params,omitempty"`
Quarantine bool `gorm:"not null;default:false;index" json:"quarantine"`
// ReplayFingerprint is the scoped, server-derived idempotency fingerprint
// for quarantined replay creation. It is nullable so ordinary runs do not
// participate in the unique index.
ReplayFingerprint *string `gorm:"type:text;uniqueIndex:idx_job_runs_replay_fingerprint" json:"replay_fingerprint,omitempty"`
ReplayOverrides datatypes.JSON `gorm:"type:json" json:"replay_overrides,omitempty"`
// SchemaGateOverride records an APPROVED tier-3 `override_schema_gate` action
// for this ONE run (design-agent-in-the-loop.md action catalog). While set,
// ValidateTaskOutputSchema / ValidateTaskOutputSchemaInstance skip output
// schema enforcement for the run's tasks and say so in the log.
//
// It lives on the run rather than in Params deliberately: run params feed
// cache identity (HashInput), so stamping the bypass as a param would re-key
// the DAG and silently change what the run computes. A column is inert to
// hashing, which is what "bypass the gate, change nothing else" requires. It
// is never set by a job definition — only by the approval executor.
SchemaGateOverride bool `gorm:"not null;default:false" json:"schema_gate_override,omitempty"`
StartedAt time.Time `gorm:"not null" json:"started_at"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
Tasks []*TaskRun `gorm:"foreignKey:JobRunID;constraint:OnDelete:CASCADE" json:"tasks,omitempty"`
CacheHits int `gorm:"-" json:"cache_hits"`
ExecutedTasks int `gorm:"-" json:"executed_tasks"`
TotalTasks int `gorm:"-" json:"total_tasks"`
}
type KeyScope ¶
type KeyScope struct {
Jobs []string `json:"jobs,omitempty"`
Agent *AgentClaim `json:"agent,omitempty"`
}
KeyScope represents optional resource scoping for an API key.
A key carries at most one kind of restriction. Jobs restricts a normal principal to a set of job aliases (checked by the deny-by-default route-scope switch). Agent, when present, marks the key as a short-lived agent-session credential bound to exactly one incident's /v1/agent/* tool surface; an agent key is valid for nothing else, regardless of its Jobs field.
type LineageDataset ¶
type LineageDataset struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// TaskRunID is the FK into task_runs. Records are deleted when the parent
// task run is deleted.
TaskRunID uuid.UUID `gorm:"type:uuid;not null;uniqueIndex:idx_lineage_dataset_key,priority:1" json:"task_run_id"`
TaskRun TaskRun `gorm:"constraint:OnDelete:CASCADE" json:"-"`
// Namespace and Name form the OpenLineage dataset identity.
Namespace string `gorm:"type:text;not null;uniqueIndex:idx_lineage_dataset_key,priority:2" json:"namespace"`
Name string `gorm:"type:text;not null;uniqueIndex:idx_lineage_dataset_key,priority:3" json:"name"`
// Direction is "input" or "output" from the step's perspective.
Direction string `gorm:"type:text;not null;uniqueIndex:idx_lineage_dataset_key,priority:4" json:"direction"`
// FacetSummary is a bounded JSON object holding a digest + small facet
// summary (step name, output keys, schema keys). Full facets are emitted
// via http transport — never stored here.
FacetSummary datatypes.JSON `gorm:"type:json" json:"facet_summary,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
}
LineageDataset stores a bounded reference to a dataset observed during a task run — a namespace+name identity plus small facet summaries. Full facets are emitted out-of-process via the existing http transport; dqlite holds only what is needed for impact queries (references + digests).
The natural key is (TaskRunID, Namespace, Name, Direction): a unique index enforces this at the DB level, and callers must upsert (OnConflict DoNothing or DoUpdates) rather than plain-insert to avoid accumulating unbounded rows when a task run emits the same dataset twice. Records are deleted when the parent TaskRun is deleted (constraint:OnDelete:CASCADE).
type NotificationChannel ¶
type NotificationChannel struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Name string `gorm:"uniqueIndex;not null" json:"name"`
Type ChannelType `gorm:"type:text;not null;index" json:"type"`
Config datatypes.JSON `gorm:"type:json;not null" json:"config"`
Enabled bool `gorm:"not null;default:true" json:"enabled"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
NotificationChannel stores a configured notification destination.
type NotificationPolicy ¶
type NotificationPolicy struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Name string `gorm:"uniqueIndex;not null" json:"name"`
ChannelID uuid.UUID `gorm:"type:uuid;index;not null" json:"channel_id"`
Channel NotificationChannel `gorm:"constraint:OnDelete:CASCADE" json:"-"`
EventTypes datatypes.JSON `gorm:"type:json;not null" json:"event_types"`
Filters datatypes.JSON `gorm:"type:json" json:"filters,omitempty"`
Enabled bool `gorm:"not null;default:true" json:"enabled"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
NotificationPolicy links event types to channels with optional filters.
type RateLimitToken ¶
type RateLimitToken struct {
Resource string `gorm:"type:text;primaryKey;column:resource" json:"resource"`
WindowKey string `gorm:"type:text;primaryKey;column:window_key" json:"window_key"`
Consumed int `gorm:"not null;default:0" json:"consumed"`
LimitVal int `gorm:"column:limit_val;not null" json:"limit_val"`
ExpiresAt time.Time `gorm:"not null;index" json:"expires_at"`
}
RateLimitToken stores consumed units for one resource/window pair. This is a catalog table: resources are declared on jobs and remain low-cardinality.
func (RateLimitToken) TableName ¶
func (RateLimitToken) TableName() string
type RemediationTimer ¶
type RemediationTimer struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
// Namespace is nullable from day one (design Open Question 4).
Namespace *string `gorm:"type:text;index" json:"namespace,omitempty"`
IncidentID uuid.UUID `gorm:"type:uuid;index;not null" json:"incident_id"`
Incident Incident `gorm:"constraint:OnDelete:CASCADE" json:"-"`
// ActionID optionally links the timer to the AgentAction that scheduled it.
ActionID *uuid.UUID `gorm:"type:uuid;index" json:"action_id,omitempty"`
// Kind identifies what the sweeper should do when the timer fires
// (e.g. "snooze_retry").
Kind string `gorm:"type:text;not null" json:"kind"`
// Payload carries the fire-time parameters (e.g. target run id) as JSON.
Payload datatypes.JSON `gorm:"type:json" json:"payload,omitempty"`
Status RemediationTimerStatus `gorm:"type:text;index;not null;default:'pending'" json:"status"`
// FireAt is when the timer becomes due. Indexed so the sweeper's due-scan
// (status = pending AND fire_at <= now) is cheap.
FireAt time.Time `gorm:"not null;index" json:"fire_at"`
FiredAt *time.Time `json:"fired_at,omitempty"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
RemediationTimer is a durable snooze/retry row backing snooze_retry actions. Every existing delay in Caesium is an in-process time.NewTimer lost on restart/failover; this row survives failover so a leader-gated sweeper can fire due timers. Timers are OWNED BY THEIR INCIDENT and cancelled on any terminal transition or human take-over. Low-volume catalog row.
type RemediationTimerStatus ¶
type RemediationTimerStatus string
RemediationTimerStatus enumerates the lifecycle of a durable timer.
const ( // Pending: not yet due / not yet fired. RemediationTimerStatusPending RemediationTimerStatus = "pending" // Fired: the sweeper fired the timer's action. RemediationTimerStatusFired RemediationTimerStatus = "fired" // Cancelled: the owning incident reached a terminal transition or a human // took over, so the timer must never fire. RemediationTimerStatusCancelled RemediationTimerStatus = "cancelled" )
type ReprocessPolicy ¶
type ReprocessPolicy string
const ( ReprocessNone ReprocessPolicy = "none" ReprocessFailed ReprocessPolicy = "failed" ReprocessAll ReprocessPolicy = "all" )
type Role ¶
type Role string
Role defines the RBAC role hierarchy. admin > operator > runner > viewer
type RunCheckpoint ¶
type RunCheckpoint struct {
// RunID identifies the job run. Stored as text per existing GORM
// convention for run-owner tables.
RunID string `gorm:"type:text;primaryKey;index:idx_run_checkpoint_run_seq,priority:1" json:"run_id"`
// SequenceHigh is the highest terminal_sequence covered by this checkpoint.
// Recovery applies the checkpoint, then layers task_runs rows with a strictly
// greater terminal_sequence. Part of the primary key so each run keeps a
// history of checkpoints (pruned on archival).
SequenceHigh int64 `gorm:"primaryKey;autoIncrement:false;index:idx_run_checkpoint_run_seq,priority:2" json:"sequence_high"`
// OwnerGeneration is the RunLease.Generation of the writing owner — a fence
// column so a stale owner's checkpoint can be distinguished from the current
// owner's during a takeover race.
OwnerGeneration int64 `gorm:"not null" json:"owner_generation"`
// StateBlob is the serialized RunState snapshot (or delta). Encoding is an
// internal detail owned by the checkpoint writer/reader (JSON in v1); the
// column is opaque bytes.
StateBlob []byte `gorm:"type:blob;not null" json:"-"`
// IsIncremental is false for a full snapshot and true for a delta containing
// only the task states that changed since the prior checkpoint. Recovery
// walks back to the most recent full snapshot and applies deltas forward.
IsIncremental bool `gorm:"not null;default:false" json:"is_incremental"`
// CreatedAt is the wall-clock write time (diagnostics only; ordering uses
// SequenceHigh, never timestamps).
CreatedAt time.Time `gorm:"not null" json:"created_at"`
}
RunCheckpoint persists a point-in-time snapshot of an owner's in-memory DAG state for a run (run-owner mode, CAESIUM_RUN_OWNER_ENABLED=true). Combined with the terminal task_runs rows written after the checkpoint (terminal_sequence > sequence_high), it lets a new owner reconstruct exact run state after the previous owner crashes — recovery bounded by the checkpoint interval.
Like task_runs, a checkpoint is per-run and transactionally local to its run's other rows: it lives in the catalog DB when unsharded, and in the run's hot shard when sharding is enabled (so it appears in both models.All and hotPathModels).
type RunLease ¶
type RunLease struct {
// RunID identifies the job run. Stored as text per existing GORM convention.
RunID string `gorm:"type:text;primaryKey" json:"run_id"`
// OwnerNode is the CAESIUM_NODE_ADDRESS of the owning node.
OwnerNode string `gorm:"type:text;not null" json:"owner_node"`
// AcquiredAt is the wall-clock time the lease was written.
AcquiredAt time.Time `gorm:"not null" json:"acquired_at"`
// LeaseExpiresAt is when another node may take over via CAS UPDATE.
LeaseExpiresAt time.Time `gorm:"not null" json:"lease_expires_at"`
// Generation is incremented on every ownership transfer. All
// coordination writes include AND owner_generation = <generation> so
// stale-owner writes are rejected at the DB layer.
Generation int64 `gorm:"not null" json:"generation"`
}
RunLease records ownership of a job run for the run-owner coordination mode (CAESIUM_RUN_OWNER_ENABLED=true). Only one node owns a run at a time; fencing is enforced via the Generation field and the owner_generation column on task_runs.
This table lives in the catalog DB (cross-run, low-volume) so that any node can answer "who owns run R?" without knowing the run's hot shard.
type RunQueue ¶
type RunQueue struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
JobID uuid.UUID `gorm:"type:uuid;not null;index:idx_run_queue_job_priority_created,priority:1" json:"job_id"`
Job Job `gorm:"constraint:OnDelete:CASCADE" json:"-"`
Params datatypes.JSON `gorm:"type:json" json:"params,omitempty"`
Priority int `gorm:"not null;default:2;index:idx_run_queue_job_priority_created,priority:2,sort:desc" json:"priority"`
ClaimedBy string `gorm:"type:text;not null;default:'';index" json:"claimed_by"`
ClaimedAt *time.Time `gorm:"index" json:"claimed_at,omitempty"`
CreatedAt time.Time `gorm:"not null;index:idx_run_queue_job_priority_created,priority:3,sort:asc" json:"created_at"`
}
type SAMLAssertionReplay ¶
type SAMLAssertionReplay struct {
Issuer string `gorm:"type:text;not null;uniqueIndex:idx_saml_assertion_ids_identity" json:"issuer"`
AssertionID string `gorm:"type:text;not null;uniqueIndex:idx_saml_assertion_ids_identity" json:"assertion_id"`
ExpiresAt time.Time `gorm:"not null;index" json:"expires_at"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
}
SAMLAssertionReplay records accepted SAML assertion IDs so a signed assertion cannot be replayed against another node before it expires.
func (SAMLAssertionReplay) TableName ¶
func (SAMLAssertionReplay) TableName() string
type Session ¶
type Session struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
UserID uuid.UUID `gorm:"type:uuid;not null;index" json:"user_id"`
TokenHash string `gorm:"type:text;not null;uniqueIndex" json:"-"`
CSRFToken string `gorm:"type:text;not null" json:"-"`
AuthMethod string `gorm:"type:text" json:"auth_method"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
IdleExpiresAt time.Time `gorm:"not null" json:"idle_expires_at"`
AbsoluteExpiresAt time.Time `gorm:"not null" json:"absolute_expires_at"`
LastSeenAt *time.Time `json:"last_seen_at,omitempty"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
SourceIP string `gorm:"type:text" json:"source_ip,omitempty"`
UserAgent string `gorm:"type:text" json:"user_agent,omitempty"`
}
Session is a server-side login session. The opaque token is never stored; only its keyed hash (TokenHash) is persisted.
type Task ¶
type Task struct {
// ID, JobID and AtomID (and CreatedAt/UpdatedAt below) carry explicit
// snake_case json tags so GET /v1/jobs/:id/tasks — which serialises this
// model directly — matches every other endpoint's casing. Without them Go
// emitted the Go field names ("ID", "JobID", "AtomID", …), which every
// consumer had to shim.
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
JobID uuid.UUID `gorm:"type:uuid;index;not null" json:"job_id"`
Job Job `gorm:"constraint:OnDelete:CASCADE" json:"-"`
AtomID uuid.UUID `gorm:"type:uuid;index;not null" json:"atom_id"`
Atom Atom `gorm:"constraint:OnDelete:RESTRICT" json:"-"`
Name string `gorm:"type:text;not null;default:''" json:"name"`
Position int `gorm:"not null;default:0" json:"-"`
Type string `gorm:"type:text;not null;default:'task'" json:"type"`
NodeSelector datatypes.JSONMap `gorm:"type:json" json:"node_selector,omitempty"`
Retries int `gorm:"not null;default:0" json:"retries"`
RetryDelay time.Duration `gorm:"not null;default:0" json:"retry_delay"`
RetryBackoff bool `gorm:"not null;default:false" json:"retry_backoff"`
TriggerRule string `gorm:"type:text;not null;default:'all_success'" json:"trigger_rule"`
ReplaySafe bool `gorm:"not null;default:false" json:"replay_safe"`
// RateLimitResource and RateLimitUnits carry step scheduling metadata from
// the job definition into the durable task catalog.
RateLimitResource string `gorm:"type:text;not null;default:''" json:"rate_limit_resource,omitempty"`
RateLimitUnits int `gorm:"not null;default:0" json:"rate_limit_units,omitempty"`
// FanOutConfig carries step scheduling metadata from the job definition
// into the durable task catalog. It is JSON of pkg/jobdef.FanOut and is
// deliberately excluded from the cache identity hash.
FanOutConfig datatypes.JSON `gorm:"type:json" json:"fan_out_config,omitempty"`
CacheConfig datatypes.JSON `gorm:"type:json" json:"cache_config,omitempty"`
// OutputSchema is a JSON Schema describing this task's expected output keys.
OutputSchema datatypes.JSON `gorm:"type:json" json:"output_schema,omitempty"`
// InputSchema maps predecessor task names to JSON Schema fragments describing
// required keys from each predecessor's output.
InputSchema datatypes.JSON `gorm:"type:json" json:"input_schema,omitempty"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
type TaskCache ¶
type TaskCache struct {
Hash string `gorm:"primaryKey;type:text"`
JobID uuid.UUID `gorm:"type:uuid;not null;index:idx_task_cache_job"`
TaskName string `gorm:"type:text;not null"`
Result string `gorm:"type:text;not null"`
Output datatypes.JSON `gorm:"type:json"`
BranchSelections datatypes.JSON `gorm:"type:json"`
RunID uuid.UUID `gorm:"type:uuid;not null"`
TaskRunID uuid.UUID `gorm:"type:uuid;not null"`
// ResolvedImageDigest records the content digest folded into Hash when the
// originating task ran with digest pinning on. Nullable: empty when pinning
// was off. Stored so a cache hit can attest which image content it covers.
ResolvedImageDigest string `gorm:"type:text"`
// HashInputBlob is the canonical, secret-redacted decomposition of the
// HashInput that produced Hash, mirrored from the originating TaskRun so a
// cache *hit* can also be explained field-by-field. Nullable.
HashInputBlob datatypes.JSON `gorm:"type:json"`
// Partitions is the normalized partition list a fan-out PRODUCER emitted,
// mirrored from its TaskRun so a cache hit on the producer can still expand
// the downstream group. Without it a warm run replays the producer's result
// but has nothing to fan out from, and the group collapses to its single
// template row. Nullable: unset for every non-producer task and for every
// entry written before this column existed — cache.Entry's entryToModel
// writes a literal "[]" (not NULL/unset) whenever the ORIGINATING run
// determined its producer's list, even when that list came out empty
// (pkg/task/partition.go's partitionAccumulator.finish returns a non-nil
// []Partition{} for an explicit `##caesium::partitions []`, the documented
// way to declare zero work). So an unset column distinguishes "no list was
// ever recorded" from a written "[]" ("recorded, and it was empty") once
// read back into cache.Entry.Partitions (nil vs a non-nil empty slice,
// respectively) — the state run.Store.HasFanOutSuccessor's cache-hit gate
// depends on to tell a legacy entry apart from a legitimately empty one.
Partitions datatypes.JSON `gorm:"type:json"`
CreatedAt time.Time
ExpiresAt *time.Time `gorm:"index:idx_task_cache_expires"`
}
TaskCache stores cached task results keyed by identity hash.
type TaskEdge ¶
type TaskEdge struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey"`
JobID uuid.UUID `gorm:"type:uuid;index;not null"`
Job Job `gorm:"constraint:OnDelete:CASCADE" json:"-"`
FromTaskID uuid.UUID `gorm:"type:uuid;index:idx_task_edge_from_to;not null"`
FromTask Task `gorm:"foreignKey:FromTaskID;constraint:OnDelete:CASCADE" json:"-"`
ToTaskID uuid.UUID `gorm:"type:uuid;index:idx_task_edge_from_to;not null"`
ToTask Task `gorm:"foreignKey:ToTaskID;constraint:OnDelete:CASCADE" json:"-"`
ProvenanceSourceID string `gorm:"index"`
ProvenanceRepo string
ProvenanceRef string
ProvenanceCommit string
ProvenancePath string
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null"`
UpdatedAt time.Time `gorm:"not null"`
}
type TaskExecutionBaseline ¶
type TaskExecutionBaseline struct {
JobID uuid.UUID `json:"jobId"`
JobAlias string `json:"jobAlias"`
TaskID uuid.UUID `json:"taskId"`
TaskName string `json:"taskName"`
AtomID uuid.UUID `json:"atomId"`
BaselineRunID uuid.UUID `json:"baselineRunId"`
TriggerID uuid.UUID `json:"triggerId,omitempty"`
TriggerType string `json:"triggerType,omitempty"`
TriggerAlias string `json:"triggerAlias,omitempty"`
ReplaySafe bool `json:"replaySafe"`
Quarantine bool `json:"quarantine"`
ComputedHash string `json:"computedHash,omitempty"`
EffectiveHash string `json:"effectiveHash,omitempty"`
HashInputBlobStored bool `json:"hashInputBlobStored,omitempty"`
}
type TaskExecutionCache ¶
type TaskExecutionCache struct {
Enabled bool `json:"enabled"`
TTL time.Duration `json:"ttl"`
Version int `json:"version"`
PinDigests bool `json:"pinDigests"`
DigestTTL time.Duration `json:"digestTTL"`
// Chain is the resolved cache.chain mode. Recorded on the descriptor so
// replay and reproduce rebuild the SAME key: without it a values-mode step
// replayed from its descriptor would fold predecessor hashes back in and
// miss on every entry it should have hit. Omitempty keeps descriptors
// written before this field byte-identical.
Chain string `json:"chain,omitempty"`
// TTLNever is the resolved `cache.ttl: never`, carried for the same reason.
TTLNever bool `json:"ttlNever,omitempty"`
ComputedHash string `json:"computedHash,omitempty"`
EffectiveHash string `json:"effectiveHash,omitempty"`
HashInputBlobStored bool `json:"hashInputBlobStored,omitempty"`
}
type TaskExecutionDAG ¶
type TaskExecutionDAG struct {
Predecessors []TaskExecutionEdgeRef `json:"predecessors,omitempty"`
Successors []TaskExecutionEdgeRef `json:"successors,omitempty"`
TriggerRule string `json:"triggerRule,omitempty"`
BranchBehavior string `json:"branchBehavior,omitempty"`
EdgeMode string `json:"edgeMode,omitempty"`
TaskPosition int `json:"taskPosition"`
OutstandingPredecessors int `json:"outstandingPredecessors"`
PredecessorOutputs map[uuid.UUID]map[string]string `json:"predecessorOutputs,omitempty"`
PredecessorEffectiveHashes map[uuid.UUID]string `json:"predecessorEffectiveHashes,omitempty"`
}
type TaskExecutionDescriptor ¶
type TaskExecutionDescriptor struct {
SchemaVersion int `json:"schemaVersion"`
CapturedAt time.Time `json:"capturedAt"`
Baseline TaskExecutionBaseline `json:"baseline"`
DAG TaskExecutionDAG `json:"dag"`
Run TaskExecutionRun `json:"run"`
Runtime TaskExecutionRuntime `json:"runtime"`
Timing TaskExecutionTiming `json:"timing"`
Cache TaskExecutionCache `json:"cache"`
Schema TaskExecutionSchema `json:"schema"`
Job TaskExecutionJob `json:"job"`
ContainerSpec container.Spec `json:"containerSpec"`
KubernetesSpec *container.KubernetesSpec `json:"kubernetesSpec,omitempty"`
SecretRefs []TaskExecutionSecretRef `json:"secretRefs,omitempty"`
// FanOut is present only on a fan-out PRODUCER's descriptor, and only once
// that producer's execution has determined its partition list. Absent
// everywhere else, so every descriptor written before this field existed
// stays byte-identical.
FanOut *TaskExecutionFanOut `json:"fanOut,omitempty"`
}
TaskExecutionDescriptor is the immutable, per-TaskRun runtime envelope used by quarantined replay. Secret values are never stored; secret refs are recorded with provider identity metadata. Large object/reference capture is out of scope for descriptor schema v1 and must be added explicitly in a later schema version before replay can depend on those refs.
type TaskExecutionEdgeRef ¶
type TaskExecutionFanOut ¶
type TaskExecutionFanOut struct {
// Partitions is the normalized list (key + fingerprint + dependsOn +
// scalar attributes), in emission order. Encoded with the struct's own JSON
// tags rather than pkgtask.EncodePartitions, because this field exists to be
// read back: the canonical wire form flattens attributes to top-level keys,
// and unmarshalling that back into a Partition silently drops them (the same
// asymmetry cache.entryToModel documents).
Partitions []pkgtask.Partition `json:"partitions,omitempty"`
// PartitionsRecorded distinguishes "this producer ran and determined an
// EMPTY list" from "no list was ever recorded here" — a descriptor written
// before this field existed, or a task that is not a producer at all. A nil
// slice cannot carry that distinction through JSON (omitempty erases the
// difference between nil and []), and replay must fail closed on the second
// case while accepting the first, so the discriminator is explicit.
PartitionsRecorded bool `json:"partitionsRecorded,omitempty"`
// Groups names the fanned successor steps this producer expanded, by catalog
// task id. It is what lets replay attribute a group of N instance rows back
// to the one producer whose list it must re-expand from, without re-deriving
// fanOut.from against a job definition that may have changed since.
Groups []TaskExecutionFanOutGroup `json:"groups,omitempty"`
}
TaskExecutionFanOut is the producer-side fan-out record: the normalized partition list one producer emitted, plus the fanned successor steps that list expanded.
It exists so quarantined replay can re-materialize a fanned group WITHOUT re-running the producer. A group's instance set is a runtime property of the producer's output, and replay reconstructs a run from frozen per-TaskRun descriptors — so with nothing recorded there, replay had exactly two options, both wrong (re-expand from a re-executed producer, which reproduces a DIFFERENT run; or resolve one arbitrary sibling), and took the third: refusing fanned baselines outright. This field is the recorded list that refusal was waiting on.
It duplicates TaskRun.Partitions on purpose. That column is live run state, rewritten whenever the producer's row is re-completed; the descriptor is the immutable envelope replay is contractually built from, and is the only one of the two that travels with a descriptor served standalone over /tasks/:task/descriptor.
type TaskExecutionFanOutGroup ¶
type TaskExecutionFanOutGroup struct {
TaskID uuid.UUID `json:"taskId"`
TaskName string `json:"taskName,omitempty"`
// Skipped records that the group resolved as skipped instead of expanding,
// which is what `onEmpty: skip` does for an empty partition list.
Skipped bool `json:"skipped,omitempty"`
}
TaskExecutionFanOutGroup is one fanned successor step a producer expanded.
type TaskExecutionJob ¶
type TaskExecutionJob struct {
MaxParallelTasks int `json:"maxParallelTasks"`
Labels map[string]string `json:"labels,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
SLA datatypes.JSON `json:"sla,omitempty"`
CacheDefaults datatypes.JSON `json:"cacheDefaults,omitempty"`
TriggerConfig datatypes.JSONMap `json:"triggerConfig,omitempty"`
}
type TaskExecutionRun ¶
type TaskExecutionRuntime ¶
type TaskExecutionRuntime struct {
Engine AtomEngine `json:"engine"`
Image string `json:"image"`
ResolvedImageDigest string `json:"resolvedImageDigest,omitempty"`
// ParamEnvInterpolation records whether ${CAESIUM_PARAM_*} references in
// ContainerSpec.Env were expanded for this execution. It is an additive
// schema-v1 capability bit: descriptors captured before interpolation was
// introduced omit it and therefore retain their historical literal-env
// semantics during replay and reproduce.
ParamEnvInterpolation bool `json:"paramEnvInterpolation,omitempty"`
Command []string `json:"command,omitempty"`
CommandRaw string `json:"commandRaw,omitempty"`
WorkDir string `json:"workdir,omitempty"`
TaskType string `json:"taskType,omitempty"`
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
RetryCount int `json:"retryCount"`
RetryDelay time.Duration `json:"retryDelay"`
RetryBackoff bool `json:"retryBackoff"`
}
type TaskExecutionSchema ¶
type TaskExecutionSecretRef ¶
type TaskExecutionSecretRef struct {
Ref string `json:"ref"`
EnvKey string `json:"envKey,omitempty"`
Provider string `json:"provider,omitempty"`
Identity datatypes.JSONMap `json:"identity,omitempty"`
Verifiable bool `json:"verifiable"`
UnverifiableReason string `json:"unverifiableReason,omitempty"`
IdentityCapturedAt *time.Time `json:"identityCapturedAt,omitempty"`
}
type TaskExecutionTiming ¶
type TaskRun ¶
type TaskRun struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
JobRunID uuid.UUID `` /* 127-byte string literal not displayed */
JobRun JobRun `gorm:"constraint:OnDelete:CASCADE" json:"-"`
TaskID uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_taskrun_jobrun_task;index;not null" json:"task_id"`
Task Task `gorm:"constraint:OnDelete:CASCADE" json:"-"`
AtomID uuid.UUID `gorm:"type:uuid;index;not null" json:"atom_id"`
Engine AtomEngine `gorm:"type:text;not null" json:"engine"`
Image string `gorm:"not null" json:"image"`
Command string `gorm:"not null" json:"command"`
Status string `gorm:"type:text;index;index:idx_taskrun_claim_priority,priority:1;not null" json:"status"`
ClaimedBy string `gorm:"type:text;index;index:idx_taskrun_claim_priority,priority:5;not null;default:''" json:"claimed_by"`
ClaimExpiresAt *time.Time `gorm:"index" json:"claim_expires_at,omitempty"`
ClaimAttempt int `gorm:"not null;default:0" json:"claim_attempt"`
// RateLimitRetryAfter keeps over-limit tasks pending without letting worker
// claims or owner dispatch pick them back up before the current window rolls.
RateLimitRetryAfter *time.Time `gorm:"index" json:"rate_limit_retry_after,omitempty"`
Attempt int `gorm:"not null;default:1" json:"attempt"`
MaxAttempts int `gorm:"not null;default:1" json:"max_attempts"`
Priority int `gorm:"not null;default:2;index:idx_taskrun_claim_priority,priority:3,sort:desc" json:"priority"`
NodeSelector datatypes.JSONMap `gorm:"type:json" json:"node_selector,omitempty"`
Hash string `gorm:"type:text;index" json:"-"`
// EffectiveHash is the identity this task presents to its DOWNSTREAM
// consumers when a value-verified short-circuit was proven (design Component
// 5 / D2). Nullable: empty means "use Hash" — the common case. When this
// task re-executed because its OWN identity changed (Hash != a prior run's)
// but it produced byte-identical output to a prior successful run, this is
// set to that prior run's identity hash. Downstream PredecessorHashes reads
// COALESCE(effective_hash, hash), so a downstream task whose only changed
// input was this step sees an UNCHANGED predecessor and cache-hits — proven,
// not heuristic. Hash itself is left untouched so this task's own receipt /
// `caesium why` still reflect its true identity. See
// cache.EquivalentPriorHash for the proof and its default-to-rerun guards.
EffectiveHash string `gorm:"type:text" json:"-"`
Result string `json:"result,omitempty"`
Output datatypes.JSON `gorm:"type:json" json:"output,omitempty"`
BranchSelections datatypes.JSON `gorm:"type:json" json:"branch_selections,omitempty"`
Quarantine bool `gorm:"not null;default:false;index" json:"quarantine"`
CacheHit bool `gorm:"not null;default:false" json:"cache_hit"`
CacheEnabled bool `gorm:"not null;default:false" json:"-"`
CacheTTL time.Duration `gorm:"not null;default:0" json:"-"`
CacheVersion int `gorm:"not null;default:0" json:"-"`
// ReplaySafe snapshots the effective job/step replaySafe mark when this
// task run is materialized. Replay authorization reads this baseline value,
// not the mutable live job definition.
ReplaySafe bool `gorm:"not null;default:false" json:"replay_safe"`
// CachePinDigests snapshots whether image-digest pinning is in effect for
// this task. Like CacheEnabled/CacheTTL/CacheVersion it is scheduler-set on
// the row so distributed workers behave identically to local execution
// without reloading the job definition.
CachePinDigests bool `gorm:"not null;default:false" json:"-"`
// CacheDigestTTL snapshots how long a resolved tag->digest mapping may be
// reused before re-resolution (0 = re-resolve every check). Scheduler-set so
// distributed workers apply the same freshness window as local execution.
CacheDigestTTL time.Duration `gorm:"not null;default:0" json:"-"`
// CacheChain snapshots the resolved cache.chain mode ("transitive" default,
// or "values"). Scheduler-set beside CachePinDigests so a distributed worker
// builds the same identity key as local execution without reloading the job
// definition. Empty means transitive — that is what every row written before
// this column existed carries, and it is the mode whose hash is unchanged.
CacheChain string `gorm:"type:text" json:"-"`
// CacheTTLNever snapshots the literal `cache.ttl: never`, which suppresses
// the cache entry's expiry entirely (nil ExpiresAt) regardless of any
// inherited TTL default. It is distinct from CacheTTL == 0, which means "no
// explicit TTL" and still inherits CAESIUM_CACHE_TTL.
CacheTTLNever bool `gorm:"not null;default:false" json:"-"`
// ResolvedImageDigest records the content digest (sha256:...) the image tag
// resolved to when pinning is on. Nullable: empty/unset when pinning is off
// or the digest could not be resolved (in which case the cache key falls
// back to the literal tag).
ResolvedImageDigest string `gorm:"type:text" json:"resolved_image_digest,omitempty"`
// HashInputBlob is the canonical, secret-redacted, field-by-field JSON
// decomposition of the HashInput that produced Hash. Nullable: written only
// when caching is enabled and the hash was computed, left null otherwise.
// It lets `caesium why` report *which* input changed between two runs
// instead of only "the hashes differ". Env values are redacted in the blob;
// see cache.HashInput.CanonicalJSON.
HashInputBlob datatypes.JSON `gorm:"type:json" json:"-"`
CacheOriginRunID *uuid.UUID `gorm:"type:uuid;index" json:"cache_origin_run_id,omitempty"`
CacheCreatedAt *time.Time `json:"cache_created_at,omitempty"`
CacheExpiresAt *time.Time `gorm:"index" json:"cache_expires_at,omitempty"`
// OutputSchema snapshots the task's declared runtime output schema onto the task run.
OutputSchema datatypes.JSON `gorm:"type:json" json:"-"`
// SchemaValidation snapshots the job's schema validation mode onto the task run.
SchemaValidation string `gorm:"type:text;not null;default:''" json:"-"`
// SchemaViolations stores any output schema violations detected at runtime.
SchemaViolations datatypes.JSON `gorm:"type:json" json:"schema_violations,omitempty"`
// ExitCode is the raw process exit code the container/pod reported at task
// completion. Every engine folds this code into an atom.Result and discards
// it today; this column preserves it so the incident classifier can map
// exit-code + log-tail patterns to a failure_class (design Phase 0). Nullable:
// unset (NULL) when the task never produced an exit code (engine wait error,
// startup failure before a code was assigned). A value of 0 is a real,
// captured success code — distinct from NULL "never captured".
ExitCode *int `gorm:"type:integer" json:"exit_code,omitempty"`
ExecutionDescriptor datatypes.JSON `gorm:"type:json" json:"-"`
LogText string `gorm:"type:text" json:"-"`
LogTruncated bool `gorm:"not null;default:false" json:"-"`
Error string `json:"error,omitempty"`
RuntimeID string `json:"runtime_id,omitempty"`
OutstandingPredecessors int `gorm:"not null;index:idx_taskrun_claim_priority,priority:2" json:"outstanding_predecessors"`
// OwnerGeneration is set to the RunLease.Generation of the owning node when
// run-owner mode is active. Every coordination write by the owner
// includes AND (owner_generation = ? OR owner_generation = 0) in its WHERE
// clause — the OR = 0 keeps legacy rows (and flag-off rows) mutable by any
// node so the migration path stays gradual. Defaults to 0.
OwnerGeneration int64 `gorm:"not null;default:0" json:"owner_generation,omitempty"`
// TerminalSequence is the per-run monotonic, dense sequence number stamped on
// a task_runs row when it reaches a terminal status under run-owner mode. It
// shares a number space with run_checkpoints.sequence_high so failure
// recovery can replay "terminal rows since the last checkpoint" in a
// deterministic order (NOT wall-clock, which is skew-prone). 0 means
// "never stamped" (non-owner mode, or not yet terminal). The composite index
// (job_run_id, terminal_sequence) makes the post-checkpoint tail scan cheap.
TerminalSequence int64 `gorm:"not null;default:0;index:idx_taskrun_terminal_seq,priority:2" json:"terminal_sequence,omitempty"`
StartedAt *time.Time `json:"started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
CreatedAt time.Time `gorm:"not null;index:idx_taskrun_claim_priority,priority:4,sort:asc" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
// PartitionValue is empty for an unfanned task. For a fanned instance it is
// the partition key (the value injected as CAESIUM_PARTITION).
PartitionValue string `gorm:"type:text;not null;default:''" json:"partition_value,omitempty"`
// PartitionRetryPending marks an operator-requested per-partition retry that
// has not reached a terminal outcome yet. Store.Complete uses this durable
// provenance marker to distinguish a retry that landed in the local
// engine's shutdown window from an ordinary never-dispatched fan-out row.
// It is set only by RetryPartition and cleared by every terminal transition.
PartitionRetryPending bool `gorm:"not null;default:false" json:"-"`
// PartitionIndex is emission order (never topological order). Unfanned and
// the rewritten template row are 0. Unique with (job_run_id, task_id).
//
// The composite index kept its pre-fan-out NAME (idx_taskrun_jobrun_task)
// while changing shape from a non-unique two-column index to a UNIQUE
// three-column one. GORM's AutoMigrate matches indexes by name only and
// leaves an existing one untouched, so these tags alone would give a fresh
// database the correct index and every existing deployment the old one, with
// the uniqueness invariant silently unenforced. The explicit migration in
// pkg/db/migrations.go (MigrateTaskRunUniquePartitionIndex) drops the stale
// index before AutoMigrate runs. Do not rename or re-shape this index without
// updating that migration.
PartitionIndex int `gorm:"not null;default:0;uniqueIndex:idx_taskrun_jobrun_task" json:"partition_index"`
// PartitionCount is 0 for unfanned tasks and N for every instance of a
// fanned group.
PartitionCount int `gorm:"not null;default:0" json:"partition_count"`
// PartitionFingerprint is the optional per-unit content address
// (sha256:<64 hex>). Empty when the producer emitted a string-form partition.
PartitionFingerprint string `gorm:"type:text;not null;default:''" json:"partition_fingerprint,omitempty"`
// PartitionAttributes is the JSON object of scalar attributes from a
// structured partition (omit-when-empty).
PartitionAttributes datatypes.JSON `gorm:"type:json" json:"partition_attributes,omitempty"`
// PartitionDependsOn is the JSON array of sibling keys this instance waits
// on. Empty for string-form partitions and for instances with no in-group
// edges.
PartitionDependsOn datatypes.JSON `gorm:"type:json" json:"partition_depends_on,omitempty"`
// Partitions is the normalized emitted list, persisted on the *producer's*
// row for observability/why/replay. Empty on consumer instances.
Partitions datatypes.JSON `gorm:"type:json" json:"partitions,omitempty"`
}
type Trigger ¶
type Trigger struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Alias string `gorm:"index" json:"alias"`
Type TriggerType `gorm:"index;not null" json:"type"`
NormalizedPath string `gorm:"index" json:"-"`
Configuration string `json:"configuration"`
ProvenanceSourceID string `gorm:"index" json:"provenance_source_id"`
ProvenanceRepo string `json:"provenance_repo"`
ProvenanceRef string `json:"provenance_ref"`
ProvenanceCommit string `json:"provenance_commit"`
ProvenancePath string `json:"provenance_path"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
}
func (*Trigger) ApplyDerivedFields ¶
type TriggerType ¶
type TriggerType string
const ( TriggerTypeCron TriggerType = "cron" TriggerTypeHTTP TriggerType = "http" TriggerTypeEvent TriggerType = "event" TriggerTypeFreshness TriggerType = "freshness" )
type User ¶
type User struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Issuer string `gorm:"type:text;not null;uniqueIndex:idx_users_identity" json:"issuer"`
Subject string `gorm:"type:text;not null;uniqueIndex:idx_users_identity" json:"subject"`
Email string `gorm:"type:text;index" json:"email"`
DisplayName string `gorm:"type:text" json:"display_name,omitempty"`
Groups datatypes.JSON `gorm:"type:json" json:"groups,omitempty"`
Role Role `gorm:"type:text;not null" json:"role"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
LastLoginAt *time.Time `json:"last_login_at,omitempty"`
DisabledAt *time.Time `json:"disabled_at,omitempty"`
}
User is a human identity provisioned just-in-time from an external IdP.
func (*User) IsDisabled ¶
IsDisabled reports whether the user account has been disabled.
type WebhookEvent ¶
type WebhookEvent struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Path string `gorm:"type:text;index;not null" json:"path"`
Source string `gorm:"type:text;index" json:"source,omitempty"`
ReceivedAt time.Time `gorm:"not null;index" json:"received_at"`
Status string `gorm:"type:text;index;not null" json:"status"`
EventID uuid.UUID `gorm:"type:uuid;index" json:"event_id,omitempty"`
EventMatchedTriggers int `gorm:"not null;default:0" json:"event_matched_triggers"`
EventRunsStarted int `gorm:"not null;default:0" json:"event_runs_started"`
HTTPTriggersAccepted int `gorm:"not null;default:0" json:"http_triggers_accepted"`
HTTPRunsStarted int `gorm:"not null;default:0" json:"http_runs_started"`
HTTPTriggerIDs datatypes.JSON `gorm:"type:json" json:"http_trigger_ids,omitempty"`
HTTPJobIDs datatypes.JSON `gorm:"type:json" json:"http_job_ids,omitempty"`
AuthFailures datatypes.JSON `gorm:"type:json" json:"auth_failures,omitempty"`
Error string `gorm:"type:text" json:"error,omitempty"`
}
Source Files
¶
- agent_action.go
- agent_profile.go
- agent_session.go
- api_key.go
- approval_request.go
- atom.go
- audit_log.go
- backfill.go
- callback.go
- callback_run.go
- contract_ack.go
- dag_snapshot.go
- dataset_declaration.go
- dataset_derivation.go
- dataset_state.go
- event_trigger_match.go
- execution_event.go
- incident.go
- ingested_event.go
- internal_mtls.go
- job.go
- lineage_dataset.go
- models.go
- notification.go
- rate_limit_token.go
- remediation_timer.go
- run.go
- run_checkpoint.go
- run_lease.go
- run_queue.go
- saml.go
- session.go
- task.go
- task_edge.go
- trigger.go
- user.go
- webhook_event.go