Decisions
Every governed action must be preceded by a decision. The policy engine evaluates your rules against the input data and returns approved, blocked, or escalated.
requestDecision()
typescript
const decision = await hdb.requestDecision(input: DecisionInput): Promise<DecisionResponse>Input
typescript
interface DecisionInput {
decisionType: string; // e.g. 'payment.authorize'
action: string; // e.g. 'payment.initiate'
inputData: Record<string, unknown>; // context evaluated by policy engine
resourceType?: string; // e.g. 'payment'
resourceId?: string; // e.g. 'pay_9k2x'
idempotencyKey?: string; // prevents duplicate decisions
}Response
typescript
interface DecisionResponse {
decisionId: string; // UUID — pass this to triggerPipeline
outcome: 'approved' | 'blocked' | 'escalated';
score: number | null; // 0.0000–1.0000 risk score
rationale: string | null; // human-readable explanation
rulesApplied: string[]; // policy rule IDs that fired
executionMs: number | null; // policy evaluation latency
}Example
typescript
const decision = await hdb.requestDecision({
decisionType: 'payment.authorize',
action: 'payment.initiate',
inputData: {
actorId: 'user:alice',
amount: 15000,
currency: 'USD',
region: 'US',
},
idempotencyKey: `pay-${orderId}`,
});
if (decision.outcome === 'blocked') {
throw new Error(`Payment blocked: ${decision.rationale}`);
}
if (decision.outcome === 'escalated') {
// Queue for human review — do not execute
await notifyReviewQueue(decision.decisionId);
return;
}
// outcome === 'approved' — safe to proceedIdempotency
If you pass the same idempotencyKey twice within the deduplication window (24 hours), the second call returns the original decision without re-evaluating. Use this to safely retry on network failures.
typescript
const key = `payment-${paymentId}-${Date.now()}`;
const decision = await hdb.requestDecision({
decisionType: 'payment.authorize',
action: 'payment.initiate',
inputData: { ... },
idempotencyKey: key,
});getDecision()
Retrieve a previously issued decision by its ID.
typescript
const decision = await hdb.getDecision(decisionId: string): Promise<DecisionResponse>Example
typescript
const decision = await hdb.getDecision('dec_abc123');
console.log(decision.outcome); // 'approved'
console.log(decision.rulesApplied); // ['rbac:admin-only', 'amount:limit-check']Decision lifecycle
requestDecision()
→ policy engine evaluates rules
→ decision_requests record created
→ decision_results record created
→ DecisionResponse returned
triggerPipeline({ decisionId })
→ Stellrai validates decisionId exists + outcome = approved
→ execution proceeds
→ decision marked as consumed (cannot reuse)A decision can only be used once. Attempting to trigger two pipelines with the same decisionId will fail with DECISION_ALREADY_CONSUMED.