Documentation
¶
Index ¶
- Variables
- type Clock
- type EscalationResolution
- type EvaluationRecorder
- type EvaluationResult
- type FailureCategory
- type NoOpEvaluationRecorder
- type Orchestrator
- func (o *Orchestrator) Evaluate(ctx context.Context, req eval.DecisionRequest, raw json.RawMessage) (EvaluationResult, error)
- func (o *Orchestrator) GetEnvelopeByID(ctx context.Context, id string) (*envelope.Envelope, error)
- func (o *Orchestrator) GetEnvelopeByRequestID(ctx context.Context, requestID string) (*envelope.Envelope, error)
- func (o *Orchestrator) GetEnvelopeByRequestScope(ctx context.Context, requestSource, requestID string) (*envelope.Envelope, error)
- func (o *Orchestrator) ListEnvelopes(ctx context.Context) ([]*envelope.Envelope, error)
- func (o *Orchestrator) ListEnvelopesByState(ctx context.Context, state envelope.EnvelopeState) ([]*envelope.Envelope, error)
- func (o *Orchestrator) ResolveEscalation(ctx context.Context, res EscalationResolution) (*envelope.Envelope, error)
- func (o *Orchestrator) Simulate(ctx context.Context, req eval.DecisionRequest, _ json.RawMessage) (EvaluationResult, error)
- type RepositoryStore
Constants ¶
This section is empty.
Variables ¶
var ( ErrNilOrchestratorDependency = errors.New("orchestrator dependency is nil") ErrEmptyIdentifier = errors.New("identifier must not be empty") ErrEnvelopeNotFound = errors.New("envelope not found") ErrEnvelopeNotAwaitingReview = errors.New("envelope is not awaiting review") ErrEnvelopeAlreadyClosed = errors.New("envelope is already closed") ErrInvalidReviewDecision = errors.New("decision must be APPROVED or REJECTED") // ErrScopedRequestConflict is returned when a duplicate (request_source, // request_id) pair is submitted with a different payload hash than the // original. This indicates request identity reuse with a mutated body and // is always a caller error. ErrScopedRequestConflict = errors.New("scoped request conflict: same (request_source, request_id) submitted with a different payload") )
Functions ¶
This section is empty.
Types ¶
type EscalationResolution ¶
type EscalationResolution struct {
EnvelopeID string
Decision envelope.ReviewDecision
ReviewerID string
ReviewerKind string
Notes string
}
EscalationResolution is the input to ResolveEscalation.
type EvaluationRecorder ¶
type EvaluationRecorder interface {
RecordEvaluationDuration(outcome string, duration time.Duration)
IncrementEvaluationOutcome(outcome string, reasonCode string)
IncrementEvaluationFailure(stage string)
}
EvaluationRecorder tracks business outcomes from evaluations. Implementations should be safe for concurrent use.
Duration Semantics: RecordEvaluationDuration measures end-to-end committed evaluation latency as seen by the caller, including domain logic execution and transaction commit overhead. This will be close to but slightly higher than TransactionRecorder.RecordTransactionDuration for the same operation.
Failure Stage Semantics: IncrementEvaluationFailure distinguishes system failures from business rejections. Current stages:
- "persistence": Repository operation, audit append, or policy infrastructure failure Future stages might include: "validation", "policy_engine", "external_service"
type EvaluationResult ¶
type EvaluationResult struct {
Outcome eval.Outcome
ReasonCode eval.ReasonCode
EnvelopeID string
State envelope.EnvelopeState
Explanation string
// Policy transparency fields — always populated, never affect evaluation decisions.
//
// PolicyMode reflects the active policy evaluator's mode (e.g. "noop").
// PolicyReference echoes the resolved profile's policy_ref when set.
// PolicySkipped is true when the profile declares a policy_ref but the active
// evaluator is noop — meaning the policy step ran but had no real effect.
PolicyMode string
PolicyReference string
PolicySkipped bool
}
EvaluationResult is the typed result returned by the orchestrator.
type FailureCategory ¶
type FailureCategory string
FailureCategory represents a typed classification of evaluation failures for observability. These categories enable precise monitoring and alerting without relying on fragile string matching.
const ( FailureCategoryEnvelopePersistence FailureCategory = "envelope_persistence" FailureCategoryAuditAppend FailureCategory = "audit_append" FailureCategoryInvalidTransition FailureCategory = "invalid_transition" FailureCategoryPolicyEvaluation FailureCategory = "policy_evaluation" FailureCategoryAuthorityResolution FailureCategory = "authority_resolution" FailureCategoryResolveReview FailureCategory = "resolve_review" FailureCategoryIdempotencyConflict FailureCategory = "idempotency_conflict" FailureCategoryUnknown FailureCategory = "unknown" )
type NoOpEvaluationRecorder ¶
type NoOpEvaluationRecorder struct{}
NoOpEvaluationRecorder is a no-op implementation used as the default.
func (NoOpEvaluationRecorder) IncrementEvaluationFailure ¶
func (NoOpEvaluationRecorder) IncrementEvaluationFailure(string)
func (NoOpEvaluationRecorder) IncrementEvaluationOutcome ¶
func (NoOpEvaluationRecorder) IncrementEvaluationOutcome(string, string)
func (NoOpEvaluationRecorder) RecordEvaluationDuration ¶
func (NoOpEvaluationRecorder) RecordEvaluationDuration(string, time.Duration)
type Orchestrator ¶
type Orchestrator struct {
// contains filtered or unexported fields
}
Orchestrator coordinates the MIDAS evaluation flow.
func NewOrchestrator ¶
func NewOrchestrator( store RepositoryStore, policies policy.PolicyEvaluator, metrics EvaluationRecorder, ) (*Orchestrator, error)
NewOrchestrator constructs an Orchestrator with a real clock.
func NewOrchestratorWithClock ¶
func NewOrchestratorWithClock( store RepositoryStore, policies policy.PolicyEvaluator, metrics EvaluationRecorder, clock Clock, ) (*Orchestrator, error)
NewOrchestratorWithClock constructs an Orchestrator with an injected clock.
func (*Orchestrator) Evaluate ¶
func (o *Orchestrator) Evaluate(ctx context.Context, req eval.DecisionRequest, raw json.RawMessage) (EvaluationResult, error)
Evaluate executes the full MIDAS authority evaluation flow inside a database transaction. All repository and audit operations commit together or roll back together.
func (*Orchestrator) GetEnvelopeByID ¶
func (*Orchestrator) GetEnvelopeByRequestID ¶
func (*Orchestrator) GetEnvelopeByRequestScope ¶
func (o *Orchestrator) GetEnvelopeByRequestScope(ctx context.Context, requestSource, requestID string) (*envelope.Envelope, error)
GetEnvelopeByRequestScope retrieves an envelope by (request_source, request_id) composite key. This is the preferred lookup for scoped idempotency checks.
func (*Orchestrator) ListEnvelopes ¶
func (*Orchestrator) ListEnvelopesByState ¶
func (o *Orchestrator) ListEnvelopesByState(ctx context.Context, state envelope.EnvelopeState) ([]*envelope.Envelope, error)
ListEnvelopesByState returns all envelopes in the given lifecycle state. An empty state returns all envelopes.
func (*Orchestrator) ResolveEscalation ¶
func (o *Orchestrator) ResolveEscalation(ctx context.Context, res EscalationResolution) (*envelope.Envelope, error)
ResolveEscalation records a reviewer's decision on an escalated envelope and closes it. The envelope must be in AWAITING_REVIEW state.
Event sequence:
AuditEventEscalationReviewed — semantic record of the review decision AuditEventEnvelopeClosed — uniform close event (same as non-escalated path)
The two-event sequence means:
- "all closed envelopes" queries on AuditEventEnvelopeClosed work uniformly,
- "all reviewed escalations" queries on AuditEventEscalationReviewed work independently.
func (*Orchestrator) Simulate ¶
func (o *Orchestrator) Simulate(ctx context.Context, req eval.DecisionRequest, _ json.RawMessage) (EvaluationResult, error)
Simulate runs the full authority evaluation flow without persisting any state. It performs the same resolution and threshold checks as Evaluate but does not create an envelope, write audit events, or queue outbox messages.
Use this for hypothetical "what-if" evaluation in the Explorer sandbox. The returned EvaluationResult has an empty EnvelopeID; all other fields are populated identically to a live evaluation.
type RepositoryStore ¶
type RepositoryStore interface {
Repositories() (*store.Repositories, error)
WithTx(ctx context.Context, operation string, fn func(*store.Repositories) error) error
}
RepositoryStore abstracts transactional repository access.