Workflow Patterns
Workflow Patterns
Mentu is a workflow engine. Recipes (JSON files) compose from ten primitives to build any automation pattern — scheduled jobs, webhook-triggered pipelines, parallel fleet operations, self-correcting adversarial loops, and everything in between.
If you've used n8n, Zapier, Airflow, or similar tools, the patterns are the same: triggers fire, processing happens, output is produced. The difference is medium. Visual tools connect nodes with wires. Mentu composes primitives in JSON. The tradeoff: you lose the canvas, you gain arbitrary nesting, epistemic memory, and mechanical trust computation.
This page covers every workflow pattern the system supports today, with copy-pasteable recipe JSON for each.
Schedule Triggers
Run something on a cron schedule. The most common automation pattern.
Mentu's temporal primitive wraps cron scheduling with operational safeguards: cooldown between runs (prevents re-fire during execution), jitter (spreads load), catch-up policies (what happens when you miss a fire), circuit breakers (pause after repeated failures), and TTL (evidence expiration).
Three execution modes — pick based on whether you need an LLM:
| Mode | When to use | LLM cost |
|---|---|---|
command |
Deterministic shell tasks (scripts, builds, data pulls) | Zero |
script |
Programmatic logic in V8 sandbox with SDK access | Zero |
formula |
Agent-powered work requiring reasoning | Per-run |
Example: Zero-LLM monitor (command mode)
{
"name": "media-monitor",
"description": "RSS crawl every 15 minutes during business hours",
"schedule": "*/15 6-23 * * *",
"command": "bash ~/scripts/run-crawl.sh",
"cooldown": 600,
"ttl": 900,
"on_ttl_expire": "rerun",
"circuit_breaker_threshold": 5,
"circuit_breaker_reset_ttl": 3600,
"jitter": 30,
"catch_up": "skip",
"notify": false,
"enabled": true,
"workspace": "/Users/you/your-project"
}Save to ~/.mentu/recipes/media-monitor.json. The temporal daemon (mentud) picks it up automatically.
Example: Daily LLM report (formula mode)
{
"name": "daily-summary",
"description": "Generate a daily project summary at 7 AM",
"schedule": "0 7 * * *",
"formula": "daily-summary-exec",
"cooldown": 3600,
"ttl": 86400,
"on_ttl_expire": "decay",
"catch_up": "run_once",
"notify": true,
"enabled": true,
"workspace": "/Users/you/your-project"
}Schedule options reference
| Field | Type | Description |
|---|---|---|
schedule |
string | 5-field cron expression (minute hour day-of-month month day-of-week) |
cooldown |
int | Minimum seconds between runs |
jitter |
int | Max random delay in seconds before fire |
ttl |
int | Evidence expires after this many seconds |
on_ttl_expire |
string | "rerun", "notify", or "decay" |
catch_up |
string | Missed-run policy: "skip", "run_once", or "run_all" |
circuit_breaker_threshold |
int | Pause after N consecutive failures |
circuit_breaker_reset_ttl |
int | Seconds before auto-recovery probe after circuit break |
history_limit |
int | Max history entries to retain |
expires_at |
string | ISO8601 date after which the temporal is auto-removed |
Webhook Triggers
React to external events via HTTP. When something happens on the cloud (a CIR signal arrives, training data is ingested, a usage limit is hit), registered HTTPS endpoints receive HMAC-SHA256 signed notifications.
The webhook system spans four layers:
Available webhook events
| Event | Fires when |
|---|---|
cir.capture |
A CIR signal is pushed to the cloud |
training.ingested |
Training data is submitted |
usage.limit_reached |
An API usage limit is exhausted |
sequence.completed |
A sequence finishes (planned) |
temporal.fired |
A temporal fires (planned) |
adapter.published |
An adapter is published (planned) |
How it works
- Register a webhook via script, CLI, or API — specifying the event, HTTPS endpoint, and signing secret (min 16 chars)
- Cloud delivers when the event occurs — payload is HMAC-SHA256 signed with your secret, sent with
X-Mentu-Signature,X-Mentu-Event, andX-Mentu-Deliveryheaders - Consumer verifies the signature and dispatches a recipe with
--varinjection
The consumer can be:
- Local: A Bun script (
~/.mentu/scripts/webhook-receiver.ts) that verifies HMAC and spawnsmentu sequence <recipe> --var EVENT=... --var SOURCE=... - Edge: A Cloudflare Worker (
~/.mentu/templates/webhook-worker/) that verifies via Web Crypto and forwards to your local receiver
Example: Webhook-triggered recipe
{
"name": "on-webhook-event",
"type": "formula",
"model": "claude-sonnet-4-20250514",
"env": {
"EVENT": "unknown",
"SOURCE": "webhook",
"ROUTE": ""
},
"steps": [
{
"label": "react-to-event",
"prompt_file": "prompts/on-webhook-event/react.md"
}
]
}The prompt can use $EVENT, $SOURCE, $ROUTE — injected at Layer 3 by the webhook receiver. Manual test:
mentu sequence on-webhook-event --var EVENT=cir.capture --var SOURCE=testRegistering from a script
// Inside a mentu script (V8 sandbox)
const hook = mentu.webhook.register(
'cir.capture',
'https://myapp.com/hook',
'my-secret-at-least-16ch'
);
console.log('Registered:', hook.id);
// Test delivery
const result = mentu.webhook.test(hook.id);
console.log('Delivered:', result.delivered);Operational features
- Delivery history —
GET /webhooks/:id/deliveriesreturns up to 25 recent deliveries with status, attempts, response code - Circuit breaker — webhooks are automatically disabled after 5 consecutive delivery failures. Re-register to re-enable.
- Richer payloads —
usage.limit_reachedincludesused,remaining,tier;cir.captureandtraining.ingestedincludetier
Event-Driven Reactions
Beyond webhooks, mentu can react to local events: file changes, shell conditions, CIR signal patterns.
The sentinel primitive runs continuous heartbeat-driven monitoring with progressive escalation. Four watch sources:
| Source | What it watches |
|---|---|
| CIR | CIR signal patterns (severity thresholds, trust decay, contradictions) |
| Shell | Shell command exit codes (health checks, process monitors) |
| File | File system changes (config drift, log patterns) |
| Formula | Formula output analysis (semantic monitoring) |
Sentinels don't just watch — they escalate. A sentinel has an attention budget and escalation chain: observe → notify → investigate → remediate.
Example: Trust decay monitor
{
"name": "trust-monitor",
"type": "sentinel",
"watch": "cir",
"query": "trust_score < 0.3 AND domain = 'production'",
"interval": 300,
"escalation": [
{ "level": "notify", "after": 1 },
{ "level": "investigate", "after": 3, "formula": "investigate-trust-decay" },
{ "level": "remediate", "after": 5, "formula": "remediate-trust-issue" }
],
"attention_budget": 3600,
"auto_resolve": true
}Reactive gates in compound workflows
Inside a compound workflow, gates between execution waves can query CIR and modify the execution graph:
- Inject: Add a layer that wasn't in the original plan
- Skip: Skip the next layer based on evidence
- Abort: Halt the entire compound
This is intra-compound reactivity — the workflow adapts based on what it learned in earlier waves.
Conditional Branching
Execute different paths based on conditions. Three levels of granularity:
Step-level: skip_if / run_if
Individual steps within a formula can have shell-expression guards:
{
"steps": [
{
"label": "build",
"prompt_file": "prompts/build.md"
},
{
"label": "deploy-staging",
"prompt_file": "prompts/deploy-staging.md",
"run_if": "test -f .build/success"
},
{
"label": "notify-failure",
"prompt_file": "prompts/notify-failure.md",
"skip_if": "test -f .build/success"
}
]
}The guard is a shell expression evaluated by /bin/bash -c. Exit code 0 = true.
Pipeline-level: conditional sequencing
Pipelines chain formulas with conditions between them:
{
"name": "build-test-deploy",
"type": "pipeline",
"formulas": [
{ "name": "build-project", "condition": "always" },
{ "name": "run-tests", "condition": "success" },
{ "name": "deploy-production", "condition": "success" },
{ "name": "rollback", "condition": "failure" }
]
}Compound-level: CIR-driven gates
Between layers in a compound workflow, gates query the CIR substrate and make routing decisions based on accumulated evidence.
Parallel Execution
Run multiple formulas concurrently. Three levels:
Formula-level: step DAG
Steps within a formula can declare dependencies. Independent steps run in parallel:
{
"steps": [
{ "label": "fetch-api-data", "prompt_file": "prompts/fetch-api.md" },
{ "label": "fetch-db-data", "prompt_file": "prompts/fetch-db.md" },
{
"label": "merge-results",
"prompt_file": "prompts/merge.md",
"depends_on": ["fetch-api-data", "fetch-db-data"]
}
]
}fetch-api-data and fetch-db-data run simultaneously. merge-results waits for both.
Parallel primitive: fleet execution
The parallel primitive runs N formulas concurrently in isolated git worktrees:
{
"name": "audit-fleet",
"type": "parallel",
"formulas": [
"audit-repo-alpha",
"audit-repo-beta",
"audit-repo-gamma",
"audit-repo-delta",
"audit-repo-epsilon"
],
"worktree_isolation": true,
"rate_limit": 3
}Fleet coordination includes: rate limit sharing (control concurrent API calls), progress tracking, and cost estimation across all branches.
Compound-level: layer parallelism
Layers within a compound can run in parallel when they have no dependency edges between them.
Multi-Phase Pipelines
Chain formulas into sequential workflows with failure handling.
Pipeline
{
"name": "release-pipeline",
"type": "pipeline",
"formulas": [
{ "name": "lint-and-typecheck" },
{ "name": "run-test-suite" },
{ "name": "build-artifacts" },
{ "name": "deploy-staging" },
{ "name": "smoke-test-staging", "condition": "success" },
{ "name": "deploy-production", "condition": "success" }
]
}If any formula fails, subsequent "condition": "success" formulas are skipped. You can add "condition": "failure" formulas for rollback or notification.
Resume from failure
mentu pipeline release-pipeline --from 4Picks up at formula 4 (deploy-staging), preserving all prior evidence.
Compound: DAG of layers
For workflows that aren't purely sequential, compound supports arbitrary DAGs. Each layer can be any primitive type (formula, parallel, pipeline, adversarial, convergent, temporal, sentinel, substrate):
{
"name": "complex-release",
"type": "compound",
"layers": [
{ "name": "prepare", "type": "formula", "formula": "prepare-release" },
{ "name": "test", "type": "parallel", "formulas": ["test-unit", "test-integration", "test-e2e"] },
{ "name": "review", "type": "adversarial", "blue": "propose-release", "red": "challenge-release" },
{ "name": "deploy", "type": "pipeline", "formulas": [
{ "name": "deploy-staging" },
{ "name": "deploy-production", "condition": "success" }
]}
],
"dependencies": {
"test": ["prepare"],
"review": ["test"],
"deploy": ["review"]
}
}Adversarial Verification
Quality assurance as a first-class primitive. No equivalent in n8n, Zapier, or Airflow.
The adversarial primitive runs two agents against each other:
- Blue agent produces work (writes code, drafts a plan, generates a report)
- Red agent attacks Blue's output (finds bugs, identifies flaws, challenges assumptions)
- Trust scores adjust based on the exchange
- Contradictions propagate through the CIR citation graph
{
"name": "secure-code-review",
"type": "adversarial",
"blue": {
"formula": "implement-feature",
"role": "Write the implementation"
},
"red": {
"formula": "attack-implementation",
"role": "Find security vulnerabilities, logic errors, and edge cases"
},
"rounds": 2,
"trust_threshold": 0.7
}After each round, Red's findings feed back to Blue. The loop continues until the trust threshold is met or rounds are exhausted. The system is self-correcting — each round improves the output based on adversarial pressure.
Convergent Selection
Run N independent approaches to the same problem, then mechanically select the best.
The convergent primitive executes multiple formulas in parallel (via fleet), then applies a selection strategy:
| Strategy | How it works |
|---|---|
| Trust score | Highest mechanical trust wins |
| Contradiction count | Fewest contradictions wins |
| Evaluation formula | A separate formula judges all outputs |
| Vote | Multiple evaluators vote |
| Benchmark | Measured performance on a test suite |
| Cost-weighted | Best result per dollar spent |
{
"name": "best-of-three",
"type": "convergent",
"approaches": [
{ "formula": "approach-a", "description": "Recursive solution" },
{ "formula": "approach-b", "description": "Iterative solution" },
{ "formula": "approach-c", "description": "Functional solution" }
],
"selection": "trust_score",
"min_approaches": 2
}Losing approaches become negative evidence in CIR — the system remembers what was tried and rejected, not just what was selected.
Scripted Orchestration
For workflows that need programmatic logic — conditionals, loops, API calls, dynamic decisions — mentu scripts run in a V8 sandbox with a frozen mentu SDK global.
// ~/.mentu/scripts/smart-dispatch.ts
const signals = mentu.cir.query({
domain: 'production',
minTrust: 0.5,
limit: 10
});
if (signals.length === 0) {
console.log('No production signals — skipping');
Deno.exit(0);
}
const highSeverity = signals.filter(s => s.severity > 0.7);
if (highSeverity.length > 3) {
// Critical: run full investigation
mentu.sequence.run('investigate-production', {
vars: { SIGNAL_COUNT: String(highSeverity.length) }
});
} else {
// Normal: run routine check
mentu.sequence.run('routine-check');
}SDK namespaces available in scripts
| Namespace | What it does |
|---|---|
mentu.cir |
Query signals, capture evidence, read trust scores |
mentu.sequence |
Run recipes programmatically |
mentu.vault |
Read/write secrets (scoped to the script's context) |
mentu.webhook |
Register, list, test, delete webhooks |
mentu.temporal |
Manage scheduled jobs |
servers.<id> |
Call any configured MCP server's tools |
Running a script
mentu script run smart-dispatchScripts can also be the execution target of a temporal (scheduled script orchestration).
External Automation
Mentu's webhook system turns any external automation platform into a visual dashboard for mentu events. Register a webhook pointing at the platform's trigger URL — the platform handles the visual workflow builder. No custom dashboard code needed.
Cloud webhooks → n8n
Start n8n locally and register mentu webhooks pointing at n8n's webhook trigger URLs:
# Start n8n (one command, no Docker)
npx n8n
# Opens at http://localhost:5678
# In n8n: create a Webhook node, copy its test URL, then:
mentu webhook register \
--event cir.capture \
--url http://localhost:5678/webhook-test/mentu-cir \
--secret "$(openssl rand -hex 16)"n8n receives the full signed payload. From there, use n8n's 400+ integrations: Slack notifications, spreadsheet logging, API calls, conditional branching — all visual.
Exposing n8n for cloud delivery: Cloud webhooks from api.mentu.ai require HTTPS. Options:
npx n8n --tunnel— n8n provides a temporary public HTTPS URLcloudflared tunnel— Cloudflare Tunnel for a stable HTTPS endpoint- Local Bun receiver as proxy —
webhook-receiver.tsaccepts from cloud, forwards to n8n locally
Cloud webhooks → Zapier
Zapier provides HTTPS endpoints out of the box — no tunnel needed. Cloud webhooks from api.mentu.ai deliver directly.
- Create a new Zap with Webhooks by Zapier as the trigger (choose "Catch Hook")
- Copy the webhook URL Zapier generates
- Register it with mentu:
mentu webhook register \
--event usage.limit_reached \
--url https://hooks.zapier.com/hooks/catch/YOUR_ID/YOUR_HOOK/ \
--secret "$(openssl rand -hex 16)"Zapier receives the signed JSON payload. Use it to trigger any of Zapier's 6,000+ app integrations — Slack alerts, Google Sheets logging, Jira ticket creation, email notifications.
The payload for usage.limit_reached includes used, remaining, tier, and route — all available as fields in Zapier's workflow builder.
Cloud webhooks → Make
Make (formerly Integromat) works the same way — HTTPS endpoint, no tunnel.
- Create a new scenario with a Custom Webhook module as the trigger
- Copy the webhook URL Make generates
- Register it with mentu:
mentu webhook register \
--event cir.capture \
--url https://hook.us1.make.com/YOUR_HOOK_ID \
--secret "$(openssl rand -hex 16)"Make parses the incoming JSON automatically. Use its visual router to branch on event fields — e.g., route cir.capture signals with severity > 0.7 to PagerDuty, others to a log spreadsheet.
Cloud webhooks → Cloudflare Workers
Cloudflare Workers run at the edge with HTTPS built in — zero infrastructure to manage. A starter template is included at ~/.mentu/templates/webhook-worker/.
# Scaffold from template
cp -r ~/.mentu/templates/webhook-worker my-mentu-worker
cd my-mentu-worker
# Set the signing secret
npx wrangler secret put WEBHOOK_SECRET
# Deploy
npx wrangler deployThe worker verifies the HMAC-SHA256 signature using crypto.subtle, then either:
- Forwards to a dispatch URL (set
DISPATCH_URLsecret) — useful for routing verified events to internal services - Processes inline — extend the worker with KV, Queues, D1, or R2 for storage
Register the worker URL with mentu:
mentu webhook register \
--event cir.capture \
--url https://my-mentu-worker.YOUR_SUBDOMAIN.workers.dev \
--secret "$(openssl rand -hex 16)"Workers are ideal for always-on receivers that don't need a running server. Pair with Cloudflare Queues for reliable async processing.
Cloud webhooks → Airtable
Airtable automations can trigger on incoming webhooks and run scripts that update tables, send notifications, or call external APIs.
- In Airtable, create an Automation with "When webhook received" as the trigger
- Copy the webhook URL Airtable generates
- Register it with mentu:
mentu webhook register \
--event usage.limit_reached \
--url https://hooks.airtable.com/workflows/YOUR_HOOK_ID \
--secret "$(openssl rand -hex 16)"Add a "Run a script" action to process the payload:
// Airtable automation script
let payload = input.config();
let table = base.getTable('Mentu Events');
await table.createRecordAsync({
'Event': payload.event,
'Tier': payload.tier,
'Used': payload.used,
'Remaining': payload.remaining,
'Timestamp': new Date().toISOString()
});
console.log(`Logged ${payload.event} event`);This turns an Airtable base into a structured event log — filterable, sortable, with views and dashboards built in.
Cloud webhooks → Python scripts
A minimal Python receiver for environments where you want full control. Works with any HTTP framework.
#!/usr/bin/env python3
"""mentu webhook receiver — verify + dispatch"""
import hashlib, hmac, json, subprocess, os
from http.server import HTTPServer, BaseHTTPRequestHandler
SECRET = os.environ["WEBHOOK_SECRET"].encode()
RECIPE = os.environ.get("RECIPE", "on-webhook-event")
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
body = self.rfile.read(int(self.headers["Content-Length"]))
sig = self.headers.get("X-Mentu-Signature", "")
expected = hmac.new(SECRET, body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, sig):
self.send_response(401)
self.end_headers()
return
event = self.headers.get("X-Mentu-Event", "unknown")
payload = json.loads(body)
# Dispatch to mentu sequence
subprocess.Popen(["mentu", "sequence", RECIPE,
"--var", f"EVENT={event}",
"--var", f"TIER={payload.get('tier', '')}"])
self.send_response(200)
self.end_headers()
self.wfile.write(b'{"dispatched": true}')
HTTPServer(("", 9876), Handler).serve_forever()Run it behind a reverse proxy (nginx, Caddy) for HTTPS, or use cloudflared tunnel to expose it directly.
Cron + CLI
For periodic automation without webhooks, standard cron calls mentu directly:
# crontab -e
# Run a recipe every hour
0 * * * * /Users/you/.local/bin/mentu sequence hourly-check 2>&1 >> ~/.mentu/cron.log
# Query CIR every 15 minutes, pipe to a script
*/15 * * * * /Users/you/.local/bin/mentu cir query --domain production --format json | python3 ~/scripts/alert-on-decay.pymentu also has its own temporal system with cooldown, jitter, and circuit breaker — see Schedule Triggers. Use system cron when you need to integrate with existing crontabs or when the trigger is external to mentu.
Local EventBus → n8n (bridge)
Cloud webhooks cover 6 API event types. The local EventBus emits 20+ execution events in real time via Unix socket (~/.mentu/mentu-local.sock): gate.await, phase_complete, fleet_complete, error, lifecycle_update, and more.
A bridge script connects to the socket and POSTs each event to an n8n webhook URL. This unlocks real-time execution monitoring:
gate.await→ Slack message asking for human approvalphase_complete→ log cost/duration to a spreadsheetfleet_complete→ trigger a deployment pipelineerror→ page on-call
The bridge recipe (eventbus-n8n-bridge) builds and runs this script. See ~/.mentu/recipes/eventbus-n8n-bridge.json.
Why not a custom dashboard?
mentu is file-based. n8n (or Zapier, Make, etc.) provides the visual layer. The platform receives structured events, you build the workflows visually. One webhook registration replaces hundreds of lines of dashboard code.
Human-in-the-Loop
Pause execution for human review. The gate system lets workflows present evidence and wait for a decision.
When a gate fires, the engine:
- Writes
gate.jsonwith an evidence snapshot (trust scores, cost, tokens, crash traces) - Pauses execution
- Polls for
decision.json
The human (or an external system) writes a decision:
{
"action": "continue",
"reason": "Reviewed the changes, looks good"
}Available actions: continue, modify (with instructions), skip (skip this step), abort (halt everything).
Permission modes
Recipes can set permission_mode to control how much autonomy the agent has:
| Mode | Behavior |
|---|---|
plan |
Agent proposes actions, human approves each one |
auto |
Agent acts autonomously, gates fire at defined checkpoints |
bypassPermissions |
Full autonomy, no gates (use with caution) |
{
"name": "deploy-production",
"type": "formula",
"permission_mode": "plan",
"steps": [
{
"label": "prepare-deploy",
"prompt_file": "prompts/prepare-deploy.md"
},
{
"label": "execute-deploy",
"prompt_file": "prompts/execute-deploy.md"
}
]
}Composition
The ten primitives form a closed algebra. Any primitive can embed any other. This table shows what nests inside what:
| Outer | Inner | How |
|---|---|---|
| Formula | Step | Every formula is a sequence of steps |
| Formula | Step (parallel) | depends_on enables DAG-parallel steps within a formula |
| Pipeline | Formula | Pipeline chains formulas sequentially |
| Parallel | Formula | Fleet runs formulas concurrently in isolated worktrees |
| Compound | Formula | Layer type "formula" |
| Compound | Parallel | Layer type "parallel" |
| Compound | Pipeline | Layer type "pipeline" |
| Compound | Compound | Recursive (with depth limiting and cycle detection) |
| Compound | Adversarial | Layer type "adversarial" |
| Compound | Convergent | Layer type "convergent" |
| Compound | Temporal | Layer type "temporal" — compound controls timing, schedule bypassed |
| Compound | Sentinel | Non-blocking background monitor for the compound's lifetime |
| Compound | Substrate | Layer type "substrate" — meta-operations with approval gates |
| Adversarial | Formula | Blue and Red are both formulas |
| Convergent | Formula | Each approach is a formula, run in parallel |
| Temporal | Formula | Each fire executes a formula via subprocess |
The embedding principle: a step runs identically whether it is the only step, one of 20 in a formula, or one of 200 across a compound. Trust computation is always per-step. The ledger sees individual step signals regardless of which primitive invoked them.
Copy-pasteable Recipes
Copy-pasteable recipes for common patterns.
Cron job (zero LLM)
{
"name": "nightly-backup",
"schedule": "0 2 * * *",
"command": "bash ~/scripts/backup.sh",
"cooldown": 3600,
"catch_up": "skip",
"circuit_breaker_threshold": 3,
"notify": true,
"enabled": true,
"workspace": "/Users/you/project"
}CI/CD pipeline
{
"name": "ci-pipeline",
"type": "pipeline",
"formulas": [
{ "name": "lint-check" },
{ "name": "unit-tests", "condition": "success" },
{ "name": "integration-tests", "condition": "success" },
{ "name": "deploy", "condition": "success" },
{ "name": "notify-failure", "condition": "failure" }
]
}Multi-repo parallel audit
{
"name": "security-audit",
"type": "parallel",
"formulas": [
"audit-api-server",
"audit-frontend",
"audit-worker",
"audit-infra",
"audit-sdk"
],
"worktree_isolation": true,
"rate_limit": 3
}Adversarial code review
{
"name": "adversarial-review",
"type": "adversarial",
"blue": {
"formula": "write-feature",
"role": "Implement the feature with tests"
},
"red": {
"formula": "break-feature",
"role": "Find bugs, security issues, and edge cases"
},
"rounds": 2,
"trust_threshold": 0.8
}Convergent best-of-3
{
"name": "best-approach",
"type": "convergent",
"approaches": [
{ "formula": "approach-recursive" },
{ "formula": "approach-iterative" },
{ "formula": "approach-functional" }
],
"selection": "trust_score"
}Compound DAG with gates
{
"name": "full-release",
"type": "compound",
"layers": [
{ "name": "build", "type": "formula", "formula": "build-all" },
{ "name": "test", "type": "parallel", "formulas": ["test-unit", "test-e2e"] },
{ "name": "verify", "type": "adversarial", "blue": "propose-release", "red": "challenge-release" },
{ "name": "stage", "type": "formula", "formula": "deploy-staging" },
{ "name": "ship", "type": "formula", "formula": "deploy-production" }
],
"dependencies": {
"test": ["build"],
"verify": ["test"],
"stage": ["verify"],
"ship": ["stage"]
},
"gates": {
"ship": { "type": "manual", "message": "Approve production deploy?" }
}
}Scripted orchestration
mentu script run smart-dispatchWhere ~/.mentu/scripts/smart-dispatch.ts:
const signals = mentu.cir.query({ domain: 'production', minTrust: 0.5 });
const critical = signals.filter(s => s.severity > 0.7);
if (critical.length > 0) {
mentu.sequence.run('investigate-production', {
vars: { COUNT: String(critical.length) }
});
} else {
console.log('All clear');
}