postgres

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package postgres implements the Fenced kernel persistence contract on PostgreSQL. Every lifecycle mutation and its outbox event share a transaction.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AccountingReconciliation

type AccountingReconciliation struct {
	TaskLedgerDrift      int64
	QuotaReservedDrift   int64
	ModelLedgerDrift     int64
	ProviderReceiptGaps  int64
	WorkflowCounterDrift int64
	Repaired             bool
}

AccountingReconciliation reports drift between append-only ledgers and their materialized counters. ProviderReceiptGaps are observable but never auto-repaired because external provider evidence is required.

type Store

type Store struct {
	// contains filtered or unexported fields
}

func New

func New(pool *pgxpool.Pool) *Store

func NewWithClock

func NewWithClock(pool *pgxpool.Pool, clock func() time.Time) *Store

NewWithClock permits deterministic lease-expiry tests. Production callers should use New so wall-clock ownership remains internal to the store.

func (*Store) AcknowledgeIPCMessages

AcknowledgeIPCMessages records a consumer's receipts for a batch of messages. The whole batch is validated before any receipt is written, and a message that does not exist in the tenant rejects the batch: a receipt is keyed by message id, so acknowledging an id that does not exist yet would permanently hide the real message from this consumer if it were stored later.

A message may be acknowledged by any consumer of the tenant; the receipt is scoped by consumer name, so acknowledging a message the caller never read affects only that caller's own drain. Which consumer may receipt which mailbox is an authorization concern this layer does not own.

func (*Store) AcquireAttempt

func (*Store) AcquireCircuit

func (s *Store) AcquireCircuit(ctx context.Context, in provider.CircuitAcquire) (provider.CircuitPermit, error)

AcquireCircuit coordinates closed/open/half-open state across gateway replicas. The row lock makes the half-open probe token globally exclusive.

func (*Store) AggregateMetrics

func (s *Store) AggregateMetrics(ctx context.Context, tenantID string, since time.Time) (*observability.Metrics, error)

AggregateMetrics computes the §Phase-7 core metrics over a tenant's workflow window (since, inclusive).

func (*Store) AppendIPCMessage

AppendIPCMessage stores one message in the recipient's mailbox.

A message stored for the first time also enqueues the IPCMessageStoredEventType dispatch event into outbox_events, in the same transaction as the row it announces. The two cannot diverge: a rolled-back send leaves no announcement, and a committed send cannot be missing one. An idempotent replay enqueues nothing, because the message it resolves to was announced by the attempt that created it.

The event payload is a notification, not the message. The body stays in the mailbox: a payload at the IPCPayloadLimit would sit close to the 1 MiB JetStream MaxMsgSize once embedded in the event envelope, and the event stream is not the place for message contents.

No audit row is written: audit attribution for IPC (which principal sent what to whom) is a later concern, so until then a stored message is not represented in the audit chain. That is a stated gap, not an oversight.

There is no retry loop around the transaction. The insert takes no row lock and leans on a unique constraint with ON CONFLICT DO NOTHING, so contention resolves as "no row returned" rather than as a lost update; a retryable conflict can only arrive as a genuine deadlock, and a deadlock surfaces to the caller as ErrRetryableTransaction, which a send may safely retry because its idempotency key makes the retry idempotent.

func (*Store) ArtifactMetadata

func (s *Store) ArtifactMetadata(ctx context.Context, tenantID, uri string) ([]byte, int64, string, error)

ArtifactMetadata reads the digest, size and media type of one artifact.

func (*Store) ClaimOutbox

func (*Store) ClaimTasks

func (*Store) ClaimWorkflows

ClaimWorkflows leases active workflows to one orchestrator instance Unclaimed or expired-claim workflows are taken round-robin across tenants so one tenant's backlog cannot crowd out the others, and a dead instance's claims expire for its peers to take over. The claim columns are internal and never touch the client-observed resource_version.

func (*Store) CompleteRun

func (*Store) CreateInstance

func (s *Store) CreateInstance(ctx context.Context, inst *supervisor.Instance) error

CreateInstance inserts a service instance and its frozen execution generation.

func (*Store) CreateNamespace

func (s *Store) CreateNamespace(ctx context.Context, ns *namespace.Namespace) error

CreateNamespace inserts a new namespace record.

func (*Store) CreateRun

func (*Store) CreateService

func (s *Store) CreateService(ctx context.Context, svc *supervisor.Service) error

CreateService inserts a new agent service record.

func (*Store) CreateWorkflow

CreateWorkflow inserts the workflow and its steps atomically. An idempotency-key replay returns the existing definition; a conflicting definition under the same key is rejected.

func (*Store) DecideAdmission

func (s *Store) DecideAdmission(ctx context.Context, in kernelstore.DecideAdmissionInput) (kernelstore.Task, error)

func (*Store) DecideWorkflowStepApproval

DecideWorkflowStepApproval records a human decision (approve/reject) on a waiting step; the decided identity is durable audit state.

func (*Store) DeferTaskSchedule

func (s *Store) DeferTaskSchedule(ctx context.Context, in kernelstore.DeferTaskScheduleInput) (kernelstore.Task, error)

DeferTaskSchedule releases the scheduling claim on a task that no pool could place and defers its next attempt until Until (O6). The deferral commits atomically with the claim release, bumps the task's resource version (so task-event streams observe it), and emits a TaskScheduleDeferred outbox event. The caller must still own the claim; stale owners are fenced.

func (*Store) DeleteInstance

func (s *Store) DeleteInstance(ctx context.Context, tenantID, serviceID, instanceID string) error

DeleteInstance deletes an instance record.

func (*Store) DeleteNamespace

func (s *Store) DeleteNamespace(ctx context.Context, tenantID, name string) error

DeleteNamespace removes a namespace if it is not "default" and has no active resources.

func (*Store) DeleteService

func (s *Store) DeleteService(ctx context.Context, tenantID, serviceID string) error

DeleteService removes a service by tenant and ID.

func (*Store) DeleteTenantQuota

func (s *Store) DeleteTenantQuota(ctx context.Context, tenantID string) error

func (*Store) ExportAuditChain

func (s *Store) ExportAuditChain(ctx context.Context, tenantID string) ([]kernelstore.AuditEvent, error)

func (*Store) FinishModelCall

func (*Store) GetAgentVersion

func (s *Store) GetAgentVersion(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.AgentVersion, error)

func (*Store) GetAgentVersionByRef

func (s *Store) GetAgentVersionByRef(ctx context.Context, tenantID, ref string) (kernelstore.AgentVersion, error)

func (*Store) GetAuditEvent

func (s *Store) GetAuditEvent(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.AuditEvent, error)

func (*Store) GetExecutionCorrelation

func (s *Store) GetExecutionCorrelation(ctx context.Context, tenantID string, workflowID uuid.UUID) (observability.ExecutionCorrelation, error)

GetExecutionCorrelation reconstructs the full execution chain of one workflow: steps, tasks, runs/attempts, model and tool calls, memory records, audit events, and idempotency receipts.

func (*Store) GetHeartbeatStatus

func (s *Store) GetHeartbeatStatus(ctx context.Context, tenantID string, attemptID uuid.UUID, fencingToken int64) (kernelstore.HeartbeatStatus, error)

GetHeartbeatStatus is the narrow lease-renewal read: the task's pending cancellation flag and the attempt's current resource version, both fenced against the run's current fencing token. Heartbeat uses this instead of re-materializing the full assignment on every renewal.

func (*Store) GetIPCMessage

func (s *Store) GetIPCMessage(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.IPCMessage, error)

GetIPCMessage returns one message. A message stored under another tenant is reported as ErrNotFound rather than as a permission failure, because tenant scoping is not a filter the caller may observe.

func (*Store) GetInstance

func (s *Store) GetInstance(ctx context.Context, tenantID, serviceID, instanceID string) (*supervisor.Instance, error)

GetInstance retrieves an instance within its tenant and service.

func (*Store) GetMemory

func (s *Store) GetMemory(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.MemoryRecord, error)

func (*Store) GetModelCall

func (s *Store) GetModelCall(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.ModelCall, error)

func (*Store) GetModelDescriptor

func (s *Store) GetModelDescriptor(ctx context.Context, tenantID, provider, modelName string) (kernelstore.ModelDescriptor, error)

func (*Store) GetNamespace

func (s *Store) GetNamespace(ctx context.Context, tenantID, name string) (*namespace.Namespace, error)

GetNamespace retrieves a namespace by tenant and name.

func (*Store) GetRunMailboxScope

func (s *Store) GetRunMailboxScope(ctx context.Context, tenantID string, runID uuid.UUID) (kernelstore.RunMailboxScope, error)

GetRunMailboxScope resolves the mailbox scope a run id names.

The agent version reference is read from the run's task rather than from the run: a run carries no version of its own, and the task held the immutable publication resolved during admission. A run id that exists in another tenant is reported as ErrNotFound, exactly like one that does not exist, because tenant scoping is not a filter the caller may observe.

func (*Store) GetRuntimeAssignment

func (s *Store) GetRuntimeAssignment(ctx context.Context, tenantID string, attemptID uuid.UUID, fencingToken int64) (kernelstore.RuntimeAssignment, error)

func (*Store) GetRuntimeReceipt

func (s *Store) GetRuntimeReceipt(ctx context.Context, tenantID string, attemptID uuid.UUID, operation, idempotencyKey string) (kernelstore.RuntimeReceipt, error)

func (*Store) GetService

func (s *Store) GetService(ctx context.Context, tenantID, serviceID string) (*supervisor.Service, error)

GetService retrieves an agent service by tenant and ID.

func (*Store) GetServiceByName

func (s *Store) GetServiceByName(ctx context.Context, tenantID, namespace, name string) (*supervisor.Service, error)

GetServiceByName retrieves an agent service by tenant, namespace, and name.

func (*Store) GetServiceTaskExecution

func (s *Store) GetServiceTaskExecution(ctx context.Context, tenantID string, taskID uuid.UUID) (supervisor.TaskExecution, error)

GetServiceTaskExecution reads the task and its current owner in one statement snapshot. A completed task remains observable after its lease is released.

func (*Store) GetTask

func (s *Store) GetTask(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.Task, error)

func (*Store) GetTaskBudget

func (s *Store) GetTaskBudget(ctx context.Context, tenantID string, taskID uuid.UUID) (kernelstore.TaskBudgetStatus, error)

func (*Store) GetTenantQuota

func (s *Store) GetTenantQuota(ctx context.Context, tenantID string) (kernelstore.TenantQuota, error)

func (*Store) GetTenantQuotaUsage

func (s *Store) GetTenantQuotaUsage(ctx context.Context, tenantID string, at time.Time) (kernelstore.TenantWindowUsage, error)

GetTenantQuotaUsage returns the settled consumption of the fixed window containing at. A tenant without a configured quota reports ErrNotFound; a tenant with a quota but no settlements yet reports zero usage.

func (*Store) GetToolApproval

func (s *Store) GetToolApproval(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.ToolApproval, error)

func (*Store) GetToolCall

func (s *Store) GetToolCall(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.ToolCall, error)

func (*Store) GetToolDescriptor

func (s *Store) GetToolDescriptor(ctx context.Context, tenantID, name, version string) (kernelstore.ToolDescriptor, error)

func (*Store) GetUsage

func (s *Store) GetUsage(ctx context.Context, tenantID, name string) (*namespace.ResourceUsage, error)

GetUsage returns the current active and settled resource usage in the namespace.

func (*Store) GetWorkflow

func (s *Store) GetWorkflow(ctx context.Context, tenantID string, id uuid.UUID) (kernelstore.Workflow, error)

GetWorkflow reads one workflow inside the tenant scope.

func (*Store) GetWorkflowStep

func (s *Store) GetWorkflowStep(ctx context.Context, tenantID string, workflowID uuid.UUID, name string) (kernelstore.WorkflowStep, error)

GetWorkflowStep returns one tenant-scoped step without rescanning the workflow. The orchestrator uses it to refresh its in-memory snapshot after a CAS transition, keeping large DAG reconciliation linear.

func (*Store) HeartbeatLease

func (*Store) ListActiveWorkflows

func (s *Store) ListActiveWorkflows(ctx context.Context, batch int) ([]kernelstore.Workflow, error)

ListActiveWorkflows returns non-terminal workflows oldest-first.

func (*Store) ListAllInstances

func (s *Store) ListAllInstances(ctx context.Context, tenantID string) ([]*supervisor.Instance, error)

ListAllInstances lists instances within a tenant.

func (*Store) ListAllServices

func (s *Store) ListAllServices(ctx context.Context) ([]*supervisor.Service, error)

ListAllServices is the internal controller enumeration. Tenant-scoped API reads must keep using ListServices, including when their tenant is empty.

func (*Store) ListAudit

func (*Store) ListExpiredAttempts

func (s *Store) ListExpiredAttempts(ctx context.Context, now time.Time, limit int) ([]kernelstore.RecoveryCandidate, error)

func (*Store) ListInstances

func (s *Store) ListInstances(ctx context.Context, tenantID, serviceID string) ([]*supervisor.Instance, error)

ListInstances lists instances belonging to one service within a tenant.

func (*Store) ListMailbox

ListMailbox drains one mailbox forward by sequence. Messages the consumer has already receipted are filtered out in the query rather than after it, so a drained batch is never shorter than the limit for a reason the caller cannot see.

func (*Store) ListNamespaces

func (s *Store) ListNamespaces(ctx context.Context, tenantID string) ([]*namespace.Namespace, error)

ListNamespaces lists all namespaces within a tenant.

func (*Store) ListRuntimePools

func (s *Store) ListRuntimePools(ctx context.Context, tenantID string) ([]scheduler.RuntimePool, error)

ListRuntimePools resolves tenant authorization dynamically from the registry and never accepts an implicit/global tenant grant.

The returned Available* fields are effective capacity: declared totals minus the pool's durable active reservation ledger, clamped at zero. A pool whose capacity ledger row was never registered by the operator is flagged CapacityLedgerMissing and fails placement closed.

func (*Store) ListServices

func (s *Store) ListServices(ctx context.Context, tenantID, namespace string) ([]*supervisor.Service, error)

ListServices lists services within a tenant, optionally filtered by namespace.

func (*Store) ListToolDescriptors

func (s *Store) ListToolDescriptors(ctx context.Context, tenantID string) ([]kernelstore.ToolDescriptor, error)

func (*Store) ListWorkflowSteps

func (s *Store) ListWorkflowSteps(ctx context.Context, tenantID string, workflowID uuid.UUID) ([]kernelstore.WorkflowStep, error)

ListWorkflowSteps returns the workflow's steps in declaration order.

func (*Store) MarkOutboxFailed

func (s *Store) MarkOutboxFailed(ctx context.Context, eventID uuid.UUID, dispatcherID string, lockToken int64, message string, retryAt time.Time) error

func (*Store) MarkOutboxPublished

func (s *Store) MarkOutboxPublished(ctx context.Context, eventID uuid.UUID, dispatcherID string, lockToken int64, publishedAt time.Time) error

func (*Store) MarkWorkflowBudgetExhausted

func (s *Store) MarkWorkflowBudgetExhausted(ctx context.Context, tenantID string, workflowID uuid.UUID, expectedVersion int64) (kernelstore.Workflow, error)

MarkWorkflowBudgetExhausted records the durable budget-stop intent; the orchestrator observes it like a cancellation and drains the workflow.

func (*Store) MarkWorkflowDeadlineExceeded

func (s *Store) MarkWorkflowDeadlineExceeded(ctx context.Context, tenantID string, workflowID uuid.UUID, expectedVersion int64) (kernelstore.Workflow, error)

MarkWorkflowDeadlineExceeded records the durable deadline-stop intent; the orchestrator then cancels active work and fails the workflow deterministically.

func (*Store) PollRuntimeAssignment

func (s *Store) PollRuntimeAssignment(ctx context.Context, tenantID, runtimeInstanceID string) (kernelstore.RuntimeAssignment, error)

func (*Store) PoolInstanceHealth

func (s *Store) PoolInstanceHealth(ctx context.Context, instanceIDs []string, now time.Time, freshness time.Duration) (map[string]bool, error)

PoolInstanceHealth derives runtime instance liveness from lease heartbeats (v0.6). An instance is presumed dead while it holds an unreleased lease that is stale: expired (expires_at <= now) or not renewed within the freshness window (heartbeat_at <= now - freshness). Released leases (normal completion or recovery takeover) and absent leases (idle workers) never mark an instance unhealthy, so recovery naturally heals a pool: the moment the stale lease is released, the pool is schedulable again.

func (*Store) PutMemory

func (*Store) ReconcileAccounting

func (s *Store) ReconcileAccounting(ctx context.Context, repair bool) (AccountingReconciliation, error)

ReconcileAccounting audits the budget, quota, and model accounting invariants. When repair is true, only counters derivable from immutable local ledger rows are corrected in one transaction.

func (*Store) ReconcileWorkflowReservations

func (s *Store) ReconcileWorkflowReservations(ctx context.Context, repair bool) (WorkflowReservationReconciliation, error)

ReconcileWorkflowReservations re-derives the token/cost reservation of every undispatched step in each flagged workflow and resyncs the usage ledger's step_reserved_* aggregate, closing the gap the 000028 upgrade could not fill in pure SQL. The token/cost ceiling of a step lives inside its merged task spec, so this reuses the exact merge the dispatcher applies — the workflow default task spec overlaid with the per-step overlay for a declared step, and the stored spec column for a dynamic step — via kernelworkflow.WorkflowSpec.StepInputs and kernelstore.TaskSpecBudgetReservation. The recomputed reservation is therefore byte-identical to what CreateWorkflow and SpawnWorkflowStep committed, never a second, divergent derivation.

Only PENDING and WAITING_APPROVAL steps hold token/cost reservations; RUNNING and terminal steps hold none (their reservation transferred to the task budget ledger at admission or was released at terminal), so they are left untouched — reconciling them would double-count against the task ledger.

Each workflow is reconciled in its own transaction with the standard lock order (workflow row, then step rows, then the usage ledger) so it can never deadlock against a concurrent spawn, step transition, or terminal release.

func (*Store) RecordCircuit

func (s *Store) RecordCircuit(ctx context.Context, in provider.CircuitRecord) error

RecordCircuit updates shared health. A stale half-open result is fenced so it cannot overwrite a newer probe's decision.

func (*Store) RecordUsageDelta

func (s *Store) RecordUsageDelta(ctx context.Context, tenantID, name string, delta namespace.ResourceUsageDelta) error

RecordUsageDelta applies incremental changes to resource usage counters.

func (*Store) RegisterRuntimePools

func (s *Store) RegisterRuntimePools(ctx context.Context, pools []scheduler.RuntimePool) error

RegisterRuntimePools upserts development/bootstrap pool declarations into the durable registry. Tenant grants are replaced per named pool atomically; unrelated pools are never deleted.

func (*Store) ReleaseTaskClaim

func (s *Store) ReleaseTaskClaim(ctx context.Context, claim kernelstore.TaskClaim) error

func (*Store) ReleaseTaskUsageReservation

func (s *Store) ReleaseTaskUsageReservation(ctx context.Context, tenantID string, taskID uuid.UUID, key string) error

func (*Store) RenewWorkflowClaim

func (s *Store) RenewWorkflowClaim(ctx context.Context, tenantID string, workflowID uuid.UUID, owner string, lease time.Duration) error

RenewWorkflowClaim extends one live orchestrator lease. A stale owner or an already-expired claim is fenced instead of being resurrected.

func (*Store) RequestTaskCancellation

func (s *Store) RequestTaskCancellation(ctx context.Context, tenantID string, taskID uuid.UUID, expectedVersion int64) (kernelstore.Task, error)

func (*Store) RequestWorkflowCancellation

func (s *Store) RequestWorkflowCancellation(ctx context.Context, tenantID string, workflowID uuid.UUID, expectedVersion int64) (kernelstore.Workflow, error)

RequestWorkflowCancellation records the durable cancel intent.

func (*Store) ReserveTaskUsage

func (s *Store) ReserveTaskUsage(ctx context.Context, in kernelstore.ReserveTaskUsageInput) error

ReserveTaskUsage atomically checks consumed + all live reservations before opening a provider-side operation. The task ledger row is the serialization point shared with settlement.

func (*Store) ScheduleTask

func (*Store) SearchMemory

func (*Store) SetTenantQuota

func (*Store) SettleTaskUsageDelta

SettleTaskUsageDelta settles the remainder between a usage family (all settlements whose key is FamilyPrefix + ":<suffix>") and a cumulative Target, under the ledger row lock so concurrent settlements cannot race the delta computation. A family that already settled at least the target settles nothing; a task without a reservation is not gated.

func (*Store) SpawnWorkflowStep

SpawnWorkflowStep creates one dynamic step with every recursion, fan-out and budget guard evaluated inside the same transaction as the insert so two racing spawn calls can never both slip past a cap. A spawn_key replay returns the existing step unchanged.

func (*Store) TombstoneMemory

func (s *Store) TombstoneMemory(ctx context.Context, tenantID string, id uuid.UUID, expectedVersion int64) (kernelstore.MemoryRecord, error)

func (*Store) TransitionAttempt

func (*Store) TransitionTask

func (s *Store) TransitionTask(ctx context.Context, tenantID string, id uuid.UUID, expectedVersion int64, to domain.TaskPhase) (kernelstore.Task, error)

func (*Store) TransitionWorkflow

TransitionWorkflow CAS-transitions the workflow status.

func (*Store) TransitionWorkflowStep

TransitionWorkflowStep CAS-transitions one step, applying the optional task id, attempt count, result summary and failure code.

func (*Store) UpdateInstance

func (s *Store) UpdateInstance(ctx context.Context, inst *supervisor.Instance) error

UpdateInstance persists all execution and drain state, including the task linkage.

func (*Store) UpdateNamespace

func (s *Store) UpdateNamespace(ctx context.Context, ns *namespace.Namespace) error

UpdateNamespace updates the metadata, labels, and quota of an existing namespace.

func (*Store) UpdateRuntimePoolStatus

UpdateRuntimePoolStatus performs an operator-authorized, CAS-guarded status transition. Cordon/drain affect new placement only; existing leases remain recoverable until their normal terminal path. The caller's subject must hold an operator grant for the pool: a tenant usage grant — which only controls scheduler visibility — is never sufficient, so one tenant of a shared pool cannot operate it for its peers. The deciding operator subject is recorded in the audit chain.

func (*Store) UpdateService

func (s *Store) UpdateService(ctx context.Context, svc *supervisor.Service) error

UpdateService updates spec, status, and updatedAt for a service.

func (*Store) UpdateToolCall

func (*Store) VerifyAuditChain

func (s *Store) VerifyAuditChain(ctx context.Context, tenantID string) (kernelstore.AuditVerification, error)

func (*Store) WithServiceLock

func (s *Store) WithServiceLock(ctx context.Context, tenantID, serviceID string, fn func(supervisor.Store) error) error

WithServiceLock serializes every operation for one service across control and controller processes. The callback store is bound to the lock transaction; its lifecycle transactions are savepoints and commit only with the callback.

func (*Store) WorkflowLineage

func (s *Store) WorkflowLineage(ctx context.Context, tenantID string, taskID uuid.UUID) (uuid.UUID, string, int64, bool, error)

WorkflowLineage resolves workflow ownership exclusively from explicit task lineage columns. Idempotency keys remain opaque and are never parsed.

func (*Store) WorkflowUsageSnapshot

func (s *Store) WorkflowUsageSnapshot(ctx context.Context, tenantID string, workflowID uuid.UUID) (kernelstore.WorkflowUsage, error)

WorkflowUsageSnapshot aggregates a workflow's task count and settled usage. Callers without a transaction use this entry point.

func (*Store) WriteRuntimeReceipt

func (s *Store) WriteRuntimeReceipt(ctx context.Context, in kernelstore.WriteRuntimeReceiptInput) error

type WorkflowReservationReconciliation

type WorkflowReservationReconciliation struct {
	Flagged       int64
	Reconciled    int64
	StepsAdjusted int64
	Repaired      bool
}

WorkflowReservationReconciliation reports the P1-05 backfill repair. Flagged counts workflows still carrying needs_budget_reconciliation at audit time; Reconciled and StepsAdjusted count the workflows cleared and the step reservation rows corrected during a repair pass.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL