Packages
@loop-engine/guards
@loop-engine/guards provides deterministic policy checks that run inside transition execution.
Install
1npm install @loop-engine/guardsGuard model
Guards in this package are synchronous policy assertions wrapped as async functions. They do not call LLMs or network services.
GuardResult:
1interface GuardResult {2 passed: boolean3 code?: string4 message?: string5 metadata?: Record<string, unknown>6}Registry API
1class GuardRegistry {2 register(guardId: GuardId, fn: GuardFunction): void3 get(guardId: GuardId): GuardFunction | undefined4 createEvaluator(): GuardEvaluator5}1import { createGuardRegistry } from "@loop-engine/guards"2import { guardId } from "@loop-engine/core"3 4const registry = createGuardRegistry()5registry.register(guardId("budget_available"), async (context) => ({6 passed: context.evidence.budget_ok === true,7 message: "Budget check failed"8}))Built-in guards
defaultRegistry pre-registers:
actor_has_permission(actorPermissionGuard)approval_obtained(approvalObtainedGuard)deadline_not_exceeded(deadlineNotExceededGuard)duplicate_check_passed(duplicateCheckPassedGuard)field_value_constraint(fieldValueConstraintGuard)
Built-in evidence keys:
approval_obtainedreadsevidence.approved === trueactor_has_permissionreadsrequired_roleandrolesdeadline_not_exceededreadsdeadline_isoduplicate_check_passedreadsduplicate_foundfield_value_constraintreadsconstraintwith operatorseq | gt | lt | in
Hard and soft behavior
Hard/soft severity is defined on each GuardSpec in @loop-engine/core. Runtime blocks on hard failures and records soft failures under _softGuardWarnings in transition evidence.