Guards

Deterministic guard evaluation engine with weighted voting and multi-agent consensus decisions.

Overview

@consensus-tools/guards is the deterministic guard evaluation engine for consensus-tools. It evaluates agent actions against 7 built-in guard types, tallies weighted votes across multiple evaluators, and computes ALLOW / BLOCK / REWRITE / REQUIRE_HUMAN decisions.

Installation

pnpm add @consensus-tools/guards

Peer dependency

This package requires @consensus-tools/schemas as a peer dependency.

Quick start

Run the built-in evaluators against an action and finalize a decision:

import { evaluatorVotes, finalizeVotes } from "@consensus-tools/guards";
import type { GuardEvaluateInput } from "@consensus-tools/schemas";

const input: GuardEvaluateInput = {
  action: { type: "code_merge", payload: { files: ["src/auth/login.ts"] } },
  context: {},
};

const votes = evaluatorVotes(input);
// => [{ evaluator: "merge-risk", vote: "REWRITE", reason: "Sensitive file touched", risk: 0.82 }]

const result = finalizeVotes(votes, "code_merge");
// => { decision: "REQUIRE_HUMAN", reason: "Sensitive file touched", risk_score: 0.82, next_step: { ... } }

API reference

evaluatorVotes(input)

Built-in deterministic evaluator for all 7 guard types.

function evaluatorVotes(input: GuardEvaluateInput): GuardVote[]
  • input GuardEvaluateInput -- the action and context to evaluate
  • Returns GuardVote[] -- array of votes from built-in evaluators

computeDecision(votes, policy, mode?)

Multi-agent weighted voting with quorum and risk threshold:

import { computeDecision } from "@consensus-tools/guards";
import type { WeightedGuardVote, GuardPolicy } from "@consensus-tools/schemas";

const votes: WeightedGuardVote[] = [
  { vote: "YES", risk: 0.3, confidence: 0.9, weight: 1, reputation: 95, evaluator: "a", reason: "ok" },
  { vote: "YES", risk: 0.2, confidence: 0.8, weight: 1, reputation: 80, evaluator: "b", reason: "ok" },
  { vote: "NO",  risk: 0.9, confidence: 0.95, weight: 1, reputation: 90, evaluator: "c", reason: "risky" },
];

const policy: GuardPolicy = { quorum: 0.6, riskThreshold: 0.7 };

const { decision, tally, quorumMet, combinedRisk } = computeDecision(votes, policy, "hybrid");
// decision: "BLOCK" (combinedRisk > threshold and NO votes present)

Weighting modes: "static" (raw weight), "reputation" (reputation/100), "hybrid" (weight × reputation/100).

Vote tallying utilities

import { computeEffectiveWeight, tallyVotes, reachesQuorum } from "@consensus-tools/guards";

// Compute a single voter's effective weight
const ew = computeEffectiveWeight(1.0, 85, "hybrid"); // => 0.85

// Tally an array of weighted votes
const tally = tallyVotes(votes, "hybrid");
// => { yes, no, rewrite, totalWeight, weightedYes, weightedNo, weightedRewrite, voterCount }

// Check if the tally meets quorum
const met = reachesQuorum(tally, 0.6);

Evaluator registry

Register custom evaluators or override built-in ones:

import { createGuardEvaluatorRegistry } from "@consensus-tools/guards";

const registry = createGuardEvaluatorRegistry();
// 7 built-in types pre-registered: send_email, code_merge, publish,
// support_reply, agent_action, deployment, permission_escalation

registry.register("custom_action", (input) => {
  return [{ evaluator: "custom", vote: "YES", reason: "Custom check passed", risk: 0.1 }];
});

const votes = registry.evaluate({ action: { type: "custom_action", payload: {} }, context: {} });
const types = registry.listTypes();

Guard templates

Create custom guard domains with the template system. Templates integrate with both the evaluator registry and the @consensus-tools/wrapper package:

import { createGuardTemplate } from "@consensus-tools/guards";

const myGuard = createGuardTemplate("custom_review", {
  rules: (payload) => [
    { evaluator: "custom", vote: "YES", reason: "Looks good", risk: 0.1 },
  ],
  description: "Custom review guard",
});

// Use as a registry evaluator
myGuard.register(registry);

// Or use as a wrapper reviewer
const reviewer = myGuard.asReviewer();

Simpler entry point

For the simplest integration path, use @consensus-tools/universal which composes guards + wrapper with sensible defaults.

Exports reference

ExportKindDescription
evaluatorVotesFunctionBuilt-in deterministic evaluator for all 7 guard types
computeEffectiveWeightFunction(weight, reputation, mode?) => number
tallyVotesFunction(votes, mode?) => VoteTally
reachesQuorumFunction(tally, quorum) => boolean
finalizeVotesFunction(votes, actionType, policy?) => GuardResult (single-evaluator path)
computeDecisionFunction(votes, policy, mode?) => { decision, tally, quorumMet, ... } (multi-agent path)
normalizeGuardTypeFunction(type) => GuardType -- falls back to "agent_action"
GuardEvaluatorRegistryClassRegistry of evaluator functions keyed by guard type
createGuardEvaluatorRegistryFunctionFactory that returns a pre-loaded registry
createGuardTemplateFunctionCreate a custom guard domain with registry + wrapper integration
EvaluatorFnType(input: GuardEvaluateInput) => GuardVote[]
  • schemas -- guard types and vote schemas
  • core -- GuardEngine that uses this package for evaluation
  • universal -- 3-line facade that uses guards as default reviewers