@idriszade/ma1-approval-gate-engine
v0.1.0
Published
Generic approval workflow: LLM risk assessment + policy compliance + decision recommendation
Downloads
37
Maintainers
Readme
MA1 — Approval Gate Engine
Generic approval workflow: takes any request and context, LLM-assesses risk and policy compliance, returns a structured decision with recommendation.
Pipeline
[input] -> validate -> buildRequestSummary (pure) -> LLM assess (risk + policy + recommendation) -> [decision + meta]LLM fires on every call. The buildRequestSummary helper is exported so downstream atoms can inspect the prompt context.
Tool surface
runMA1(input, deps?)— returnsResult<MA1Output, MA1Error>buildRequestSummary(input)— pure text builder, exported for composition- MCP tool:
ma1_approval_gate_engine
Input (key fields)
| Field | Type | Required |
|---|---|---|
| requestId | string | yes |
| requestType | string (free-text) | yes |
| requestor | { name, email?, department?, role? } | yes |
| subject | string | yes |
| amount | number | no |
| currency | string | no (default 'USD') |
| context | { source, content }[] | no (default []) |
| policies | string[] | no (default []) |
| urgency | 'critical'|'high'|'medium'|'low' | no (default 'medium') |
Output (key fields)
decision.summary, decision.riskLevel ('none'|'low'|'medium'|'high'|'critical'), decision.riskFactors[], decision.policyViolations[], decision.recommendation ('approve'|'reject'|'escalate'|'modify'), decision.confidence (0–100), decision.suggestedModifications[], meta.analysisMs, meta.contextItemCount, meta.policyCount
Test coverage
| Layer | File | Tests | What it verifies |
|---|---|---|---|
| Unit + property | tests/pipeline.test.ts | 9 | Happy path, minimal input (no context/policies), escalate path with risk factors, validation error (ma1_input_invalid), process failure propagation with ma1_assessment_ prefix, buildRequestSummary field inclusion and empty-section omission, meta.analysisMs is non-negative integer, property: recommendation always one of 4 valid enum values (10 runs) |
| Scenario | tests/scenario.test.ts | 7 | All 5 recommendation paths (approve/escalate/none/reject/modify), unicode in names/emails/currencies, large 20-item context array with contextItemCount assertion |
| Business | tests/business.test.ts | 5 | Multi-policy cascade reject ($85K AWS), just-under-threshold approval ($9,999 DataDog with cumulative reasoning), cross-department contractor access with SOC2 compliance risk, emergency P0 procurement with policy waiver, repeat-vendor frequency pattern escalation |
| Cross-atom | packages/meta-flow-tests/ | 4 | MA1 in Flow 1 (PO → A26), Flow 2 (MA2 alert → MA1 renewal), Flow 3 (MA3 discrepancy → MA1 adjustment), Flow 5 (full Meridian Corp BizOps cycle) |
Business scenarios tested
| Scenario | Domain | Business invariant |
|---|---|---|
| Multi-policy cascade ($85K AWS) | Finance / Cloud spend | All 3 concurrent policy violations are captured; recommendation is reject or escalate |
| Just-under-threshold ($9,999 DataDog) | Software procurement | Cumulative quarterly spend mentioned in reasoning; recommendation is approve |
| Contractor prod DB access | IT / SOC2 | Missing NDA blocks full access; modify with scoped alternatives |
| Emergency P0 procurement ($24.5K Dell) | IT Operations | Policy waiver for P0 incident; approve with no policy violations |
| Repeat vendor frequency (3× Meridian Advisory) | Fraud detection | Frequency pattern triggers escalate regardless of individual amount |
Composition flows
- Flow 1: MA1 → A26 — PO approval decision (
approve,confidence=92) passed to A26, which signs the event with HMAC-SHA256 and classifies it asapproval_decision - Flow 2: MA2 detects critical Stripe contract (5 days remaining) → MA1 escalates the $250K renewal for CFO sign-off; MA1 recommendation is
approveorescalate, neverreject - Flow 3: MA3 identifies $2,500
amount_mismatch→ MA1 approves the Finance Manager ledger adjustment; context item from MA3 explanation feeds directly into MA1 input - Flow 5: participates in full Meridian Corp month-end BizOps cycle alongside MA2, MA3, MA4, MA5, and A26
- Flow 6 (invariant): MA2
classifyUrgencyoutput and MA3 discrepancy output both feed MA1 without validation errors — schema compatibility proven in isolation
Error codes
| Code | Type | When |
|---|---|---|
| ma1_input_invalid | validation | Schema validation fails (empty requestId, empty requestor.name, etc.) |
| ma1_assessment_<code> | Propagated from process | LLM process returns a ProcessError; the atom prefixes its own code |
Notes on buildRequestSummary
The summary builder is exported because downstream atoms (MA3 discrepancy handler, MA2 alert handler) need to inspect the exact prompt text MA1 sends to the LLM when debugging unexpected decisions. The test suite verifies that context and policy sections are omitted entirely when empty — not rendered as empty headers — to avoid misleading the LLM with phantom structure.
A requestor.name without other fields (department, email, role) is a valid minimal input; this matches how automated systems (IT bots, reconciliation engines) submit requests programmatically.
Running
pnpm vitest run atoms/ma1-approval-gate-engine