NAAb

June 11, 2026 · View on GitHub

CI Sanitizers CodeQL License: MIT PRs Welcome Discussions

AI agents can read your secrets, encode them, and send them to an external API — all in three steps. NAAb blocks the sequence before the network call fires.

$ naab agent_task.naab

[governance] Behavioral sequence 'credential_exfiltration' blocked before execution.

  Pattern matched:
    Step 1 — env.get("API_SECRET_KEY")        ✓ matched
    Step 2 — crypto.base64_encode(secret)     ✓ matched
    Step 3 — agent.send(handle, encoded)      ✗ BLOCKED

  Rule: behavioral_sequences.credential_exfiltration [HARD]
  The sequence env.get:*KEY* → encode → agent.send matches a known
  exfiltration pattern. Execution was stopped before the API call.

No prompt engineering. No post-hoc log scanning. The agent never reaches the network.


How It Works

NAAb is a programming language with a governance engine built into the runtime. You define behavioral rules in govern.json — multi-step attack patterns, capability limits, secret scanning — and the engine enforces them as your code runs, not after.

{
  "version": "5.0",
  "mode": "enforce",
  "behavioral_sequences": {
    "enabled": true,
    "patterns": [
      {
        "name": "credential_exfiltration",
        "sequence": ["env.get:*KEY*|*SECRET*|*TOKEN*", "encode|base64", "agent.send|http.post"],
        "level": "hard",
        "rationale": "Reading credentials then encoding and sending matches exfiltration."
      },
      {
        "name": "config_harvest",
        "sequence": ["file.read:*config*|file.read:*govern*", "agent.send"],
        "level": "hard",
        "rationale": "Reading config files then sending content to an external agent."
      }
    ]
  }
}

The patterns are yours to define. The engine tracks event sequences across your entire script — with configurable gap limits, decay timers, and enforcement tiers — and blocks the final step before it executes.

What Else Gets Blocked

ThreatHow NAAb stops it
Credential exfiltrationSequence detection — env.get(SECRET) → encode → agent.send blocked pre-execution
Config harvestingfile.read(govern.json)agent.send blocked before API call
Agent driftContext Drift Detection tracks coherence across turns — circular loops, scope creep, contradictions
Leaked secrets in responsescheckSecrets() scans every agent response — API keys, JWTs, hardcoded passwords hard-blocked
Capability abusefilesystem: read mode, shell: disabled — enforced at sandbox level, not by prompt
Tainted data reaching shellVM taint tracking — env.get output reaching shell_exec blocked with full lineage trace

Governance That Can't Be Bypassed

Rules live in govern.json, not in prompts. A signed govern.json with Ed25519 means the agent can't modify its own constraints mid-run. A one-way ratchet ensures mid-run reloads can only tighten rules, never loosen them.

naab --keygen ./keys/governance
naab --sign-governance                    # Sign govern.json
naab --trust-key ./keys/governance.pub   # Install on CI

See It In Action

NAAb Governance Demo — 7 scenes catching AI mistakes

SceneAI MistakeGovernance Response
1.push() in PythonBlocked — use .append()
2import fake_ai_toolkitBlocked — unknown module
3fn validate() { return true }Blocked — stub function
4Hardcoded sk-proj-... API keyBlocked — secret detected
5Empty catch (e) { }Blocked — incomplete logic
6env.get() → shell unsanitizedBlocked — taint violation
7All issues fixedPasses clean

Run it yourself: bash demo/governance_demo.sh | Record: bash demo/governance_demo.sh --record


The Problem: AI Code Drift

AI models generate code that looks right but isn't. Every session starts fresh — no memory of your security rules, naming conventions, or architecture decisions:

  • Hallucinated APIs.push() in Python, print() in JavaScript, json.stringify() instead of json.dumps()
  • Stubs shipped as "complete"def validate(): return True, functions with only pass or NotImplementedError
  • Security patterns bypassed — hardcoded secrets, SQL injection, except: pass swallowing errors
  • Language misuse — Python for heavy computation, JavaScript for file operations, Shell for complex logic

Prompts are suggestions. govern.json is policy. NAAb checks every polyglot block against your policies before execution — where it can't be bypassed.


At a Glance

CapabilityDetails
Governance Engine50+ checks, 4-tier policy engine (hard / soft / advisory / detect), govern.json config
Polyglot Execution12 languages in one file — Python, JavaScript, Rust, C++, Go, C#, Ruby, PHP, Shell, Nim, Zig, Julia
Smart Error Messages"Did you mean?" suggestions via Levenshtein distance, detailed fixes with examples
Standard Library24 modules — array, string, math, json, http, file, path, time, debug, env, csv, regex, crypto, log, uuid, validate, process, io, bolo, agent, governance, codegen, orchestra
Language FeaturesGenerators/yield, interfaces, pattern matching with guards, f-strings, async/await, lambdas, closures, pipeline, destructuring
CI/CD IntegrationSARIF (GitHub Code Scanning), JUnit XML (Jenkins/GitLab), JSON reports
Project ContextAuto-reads CLAUDE.md, .editorconfig, .eslintrc, package.json to supplement governance
Developer ToolsInteractive REPL, URL imports, LLM-friendly syntax (keyword aliases, optional semicolons), 204 error messages
Bytecode VMStack-based compiler + VM (default engine, ~8x faster than tree-walking), computed goto dispatch, NaN-boxing fast paths, constant folding
Runtime SecurityBehavioral Sequence Detection (BSD), Context Drift Detection (CDD), VM taint lineage tracking, polyglot subprocess containment
Ed25519 SigningTrust-anchored governance — --keygen, --sign-governance, --trust-key, one-way ratchet
Cumulative ScoringAdvisory findings accumulate weighted scores — green/yellow/red zones with configurable thresholds
Agent GovernanceMulti-agent role enforcement, per-agent permissions, standing lease TTL, advisory escalation, output contracts, telemetry JSONL
Governance PulseReal-time health monitoring (HEALTHY/DEGRADED/IMPAIRED), evidence epochs, governance entropy detection
Multi-Agent Orchestrationorchestra module — sequential refinement, consensus voting, convergence enforcement
Dynamic Code Executioncodegen.run() — governed runtime code generation with same 39+ checks as static polyglot blocks
Enterprise FeaturesPolicy inheritance (extends), telemetry forwarding (webhook/SIEM), REST API multi-key auth, polyglot hot-reload
Subprocess ContainmentOS-level restrictions on polyglot child processes — RLIMIT_NPROC, PATH restriction, env scrubbing, timeout

Quick Start

# Clone and build
git clone --recursive https://github.com/b-macker/NAAb.git
cd NAAb
mkdir build && cd build
cmake .. -G Ninja
ninja naab-lang -j$(nproc)

# Run a file
./naab-lang hello.naab

# Start interactive REPL
./naab-lang

Hello World

main {
    let name = "World"
    print("Hello, " + name + "!")
}

Governance Engine

NAAb's governance engine is what sets it apart. Drop a govern.json in your project root and every polyglot block is checked before execution.

What It Catches

CategoryExamplesPatterns
Hallucinated APIs.push() in Python, print() in JS, len() in JS86+ cross-language patterns
Oversimplificationdef validate(): return True, pass-only bodies, identity functions35+ stub patterns
Incomplete Logicexcept: pass, bare raises, "something went wrong" messages40+ patterns
SecuritySQL injection, path traversal, shell injection, hardcoded secretsEntropy-based detection
Code QualityTODO/FIXME, debug artifacts, mock data, hardcoded URLs/IPsDead code detection
Taint TrackingUntrusted data (env.get, polyglot output) reaching sinks (shell, env)Source/sink/sanitizer with prefix matching
PII ExposureSSN patterns, credit card numbers, API keys in stringsRegex + entropy

Four Policy Levels

  • HARD — Block execution. Code does not run. No override. Throws uncatchable GovernanceHardError (NAAb try/catch cannot intercept it). Process exits with code 3.
  • SOFT — Block execution. Code does not run unless --governance-override is passed.
  • ADVISORY — Warn and continue. Logged in audit trail. Repeated advisories escalate to SOFT via advisory escalation.
  • DETECT — Same detection as HARD but throws catchable exception. Used in test configurations where scripts verify violations via try/catch.

govern.json Example

{
  "version": "5.0",
  "mode": "enforce",

  "languages": {
    "allowed": ["python", "javascript", "go"],
    "blocked": ["php"]
  },

  "code_quality": {
    "no_secrets": { "level": "hard" },
    "no_sql_injection": { "level": "hard" },
    "no_oversimplification": { "level": "hard" },
    "no_incomplete_logic": { "level": "soft" },
    "no_hallucinated_apis": { "level": "soft" }
  },

  "restrictions": {
    "no_eval": { "level": "hard" },
    "no_shell_injection": { "level": "hard" }
  },

  "limits": {
    "max_lines_per_block": 200,
    "timeout_seconds": 30
  }
}

Project Context Awareness

NAAb can read your existing project configuration files and supplement governance rules — without overriding govern.json:

  • Layer 1: LLM instruction files — CLAUDE.md, .cursorrules, AGENTS.md
  • Layer 2: Linter configs — .eslintrc, .flake8, pyproject.toml
  • Layer 3: Project manifests — package.json, Cargo.toml, go.mod

Each layer is opt-in and toggleable.

Custom Rules

Define your own regex-based governance rules:

{
  "custom_rules": [
    {
      "name": "no_print_debugging",
      "pattern": "console\\.log|print\\(.*debug",
      "message": "Remove debug print statements before committing",
      "level": "soft"
    }
  ]
}

CI/CD Integration

# GitHub Code Scanning (SARIF)
naab app.naab --governance-report sarif > results.sarif

# Jenkins / GitLab CI (JUnit XML)
naab app.naab --governance-report junit > results.xml

# Custom tooling (JSON)
naab app.naab --governance-report json > results.json

Build your govern.json interactively | Full governance reference (Chapter 21)

Security model & threat assumptions

Agent Governance

NAAb supports multi-agent environments where different AI agents have different permissions. Define per-agent configs in govern.json:

{
  "agents": {
    "analyzer": {
      "provider": "gemini",
      "model": "gemini-2.5-flash",
      "api_key_env": "GEMINI_API_KEY",
      "system_prompt": "You are a code analyzer.",
      "max_turns": 20,
      "max_tokens": 4096,
      "allowed_languages": ["python", "javascript"],
      "allowed_actions": ["AGENT_SEND", "FS_READ"],
      "standing_lease_turns": 10,
      "risk_budget": 15,
      "output_contract": {
        "format": "json",
        "required_fields": ["severity", "category"],
        "regex_checks": { "severity": "^(low|medium|high|critical)$" }
      }
    }
  }
}
# Run with agent identity
naab --agent-id analyzer app.naab

# View governance dashboard
naab --agent-id analyzer --governance-dashboard app.naab

Agent features:

  • Standing Lease — TTL on agent authorization. Expired lease forces step-up challenge.
  • Output Contracts — validate LLM response structure against a schema (required fields, types, regex).
  • Risk Budget — finite risk budget consumed by BSD matches and CDD signals. Agent blocked when exhausted.
  • Key Rotationapi_key_env accepts string or array. Dead keys (401) marked and rotated. key_retry_after_seconds enables revival.
  • Model Fallbackmodel accepts string or array. On 404/503, next model in chain is tried.
  • Tool Executionagent.register_tool() + governed tool loop with 7 defense layers.
  • Code Extractionagent.extract_code(response, lang) extracts code from markdown fences.
  • Environment Awarenessagent.environment(handle) returns real-time config, state, and health.

Runtime Security: BSD, CDD & Subprocess Containment

Beyond static checks, NAAb monitors runtime behavior patterns:

  • Behavioral Sequence Detection (BSD) — catches multi-step attack patterns like "read secrets → encode → exfiltrate". Patterns are fully configurable in govern.json — no hardcoded rules. Dangerous sequences are blocked before the final step executes. Pattern names accept both UPPERCASE_UNDERSCORE and lowercase.dot notation.
  • Context Drift Detection (CDD) — monitors LLM agent conversations for coherence drift: repeated failures, circular actions, scope creep, contradictions. Configurable thresholds and per-signal weights. 8 signals including coherence velocity, vocabulary contraction, capability underutilization, and semantic stability.
  • VM Taint Lineage — every tainted value carries a full chain showing where it was tainted and why, making governance violations actionable.
  • Governance Pulse — real-time self-assessment (HEALTHY/DEGRADED/IMPAIRED) with hysteresis and evidence epochs. governance.health() returns instrumentation status.
  • Polyglot Subprocess Containment — OS-level restrictions on child processes: RLIMIT_NPROC=0 (blocks fork), PATH restriction, environment scrubbing, timeout with SIGKILL. Catches runtime-constructed commands that evade static source scanning.

Ed25519 Governance Signing

Trust-anchored signing ensures govern.json integrity:

# Generate keypair
naab --keygen ./keys/governance

# Sign govern.json
naab --signing-key ./keys/governance.key --sign-governance

# Install public key on CI/team machines
naab --trust-key ./keys/governance.pub

Signed governance enforces a one-way ratchet — mid-run config reloads can only tighten restrictions, never loosen them.


Polyglot Execution

Use each language where it shines — Python for data science, Rust for performance, JavaScript for web, Go for concurrency, Shell for file ops. Variables flow between languages automatically. No FFI, no serialization, no microservices.

Supported languages: Python · JavaScript · Rust · C++ · Go · C# · Ruby · PHP · Shell · Nim · Zig · Julia

main {
    let numbers = [10, 20, 30, 40, 50]

    // Python: statistical analysis
    let stats = <<python[numbers]
import statistics
result = {
    "mean": statistics.mean(numbers),
    "stdev": statistics.stdev(numbers)
}
str(result)
>>

    // JavaScript: format as HTML
    let html = <<javascript
const data = "Stats: mean=30, stdev=15.81";
`<div class="result">${data}</div>`;
>>

    print(stats)
    print(html)
}

Key Polyglot Features

  • Variable binding — Pass NAAb variables into polyglot blocks with <<python[x, y]
  • Parallel execution — Independent blocks run concurrently with automatic dependency analysis
  • Persistent runtimes — Keep interpreter state across multiple calls with the runtime keyword
  • JSON sovereign pipe — Return structured data from any language with naab_return() or -> JSON header
  • Error mapping — Polyglot errors map back to NAAb source locations and flow into try/catch
  • Block-header awareness — Go gets package main, PHP gets <?php automatically

Language Features

Pattern Matching

main {
    let status = 404

    let message = match status {
        200 => "OK"
        404 => "Not Found"
        n if n >= 500 => f"Server Error ({n})"  // guard clause
        _ => "Unknown"
    }

    print(message)  // "Not Found"

    // Array destructuring in match
    let point = [3, 4]
    let label = match point {
        [0, 0] => "origin"
        [x, 0] => f"on x-axis at {x}"
        [0, y] => f"on y-axis at {y}"
        [x, y] => f"point ({x}, {y})"
    }
    print(label)  // "point (3, 4)"
}

Async/Await

main {
    async fn fetch_data() {
        return "data loaded"
    }

    async fn process() {
        return "processed"
    }

    let data = await fetch_data()
    let result = await process()
    print(data + " -> " + result)
}

Lambdas & Closures

main {
    let multiplier = 3
    let scale = fn(x) { return x * multiplier }

    print(scale(10))  // 30

    // Closures capture their environment
    function make_counter() {
        let count = 0
        return fn() {
            count = count + 1
            return count
        }
    }

    let counter = make_counter()
    print(counter())  // 1
    print(counter())  // 2
}

Pipeline Operator

main {
    let result = "hello world"
        |> string.upper()
        |> string.split(" ")

    print(result)  // ["HELLO", "WORLD"]
}

If Expressions

main {
    let score = 85
    let grade = if score >= 90 { "A" } else if score >= 80 { "B" } else { "C" }
    print(grade)  // "B"
}

Error Handling

main {
    try {
        let result = <<python
raise ValueError("something broke")
>>
    } catch (e) {
        print("Caught from Python: " + e)
    }
}

Generators

fn fibonacci(limit) {
    let a = 0
    let b = 1
    while a < limit {
        yield a
        let temp = a + b
        a = b
        b = temp
    }
}

main {
    for n in fibonacci(100) {
        print(n)  // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
    }
}

Interfaces

interface Printable {
    fn to_string() -> string
}

struct Point implements Printable {
    x: int
    y: int
}

fn Point.to_string(p) -> string {
    return f"({p.x}, {p.y})"
}

main {
    let p = new Point { x: 3, y: 4 }
    print(Point.to_string(p))  // "(3, 4)"
}

F-Strings

main {
    let name = "World"
    let count = 42
    print(f"Hello {name}, you have {count} items")
    print(f"Total: {count * 2}")  // expressions work too
}

More Language Features

  • Optional chaining (user?.name), null coalescing (x ?? "default", x ??= fallback)
  • Destructuring (let [a, b] = arr, let {x, y} = dict)
  • Spread/rest ([...arr1, ...arr2], fn(...args))
  • in / not in operators, array slicing (arr[1:3])
  • Structs, enums, module system with imports/exports/URL imports
  • For loops with destructuring, while loops, break/continue
  • Dictionaries and arrays with dot-notation methods

Standard Library

24 modules with 204 error messages, "Did you mean?" suggestions, and detailed documentation.

main {
    // JSON
    let data = json.parse('{"name": "NAAb", "type": "language"}')
    print(data["name"])

    // HTTP
    let response = http.get("https://api.github.com/repos/b-macker/NAAb")
    print(json.parse(response)["stargazers_count"])

    // File I/O
    file.write("output.txt", "Hello from NAAb!")

    // Math
    print(math.sqrt(144))  // 12

    // String operations
    let words = string.split("hello world", " ")
    print(string.upper(words[0]))  // "HELLO"
}
ModuleFunctions
arraypush, pop, shift, unshift, map_fn, filter_fn, reduce_fn, sort, slice_arr, find, reverse, length, contains, first, last, join
stringsplit, join, upper, lower, trim, replace, reverse, contains, starts_with, ends_with, length, char_at, index_of, substring, repeat, pad_left, pad_right
mathsqrt, pow, abs, floor, ceil, round, min, max, sin, cos, random, PI, E
jsonparse, stringify
httpget, post, put, delete, head, patch (with headers, body, timeout)
fileread, write, append, exists, delete, list_dir, create_dir, is_file, is_dir, read_lines, write_lines, copy, move, size, basename, dirname, extension
pathjoin, dirname, basename, extension, resolve, is_absolute, normalize, exists
timenow, now_millis, sleep, format_timestamp, parse_datetime, year, month, day, hour, minute, second, weekday
debuginspect, type, trace, watch, snapshot, diff, keys, values, log, timer, compare, stack, env
envget, set_var, list
csvparse, stringify
regexsearch, matches, find, find_all, replace, replace_first, split, groups, find_groups, escape, is_valid
cryptohash, sha256, sha512, md5, sha1, random_bytes, random_string, random_int, base64_encode, base64_decode, hex_encode, hex_decode, compare_digest, generate_token, hash_password
agentcreate, send, run, extract_code, register_tool, batch, fan_out, pipeline, check, key_health, dispatch_status, environment
codegenrun, run_with_args, run_strict, supported_languages, is_enabled
orchestrasequential_refinement, consensus_vote, enforce_convergence
governancehealth
boloscan, report (governance integration)

Developer Experience

Smart Error Messages

NAAb doesn't just tell you what's wrong — it tells you how to fix it:

Error: Unknown function "array.pussh"

  Did you mean: array.push ?

  Help:
  - array.push(arr, value) adds an element to the end of an array

  Example:
    ✗ Wrong: array.pussh(my_list, 42)
    ✓ Right: array.push(my_list, 42)

Common Mistake Detection

NAAb detects ~35 patterns where developers (and AI) use the wrong language's idioms:

  • array.append() → "That's Python. In NAAb, use array.push()"
  • console.log() → "That's JavaScript. In NAAb, use print()"
  • str.upper() → "Use string.upper(str) or str.upper() (dot-notation)"

LLM-Friendly Syntax

NAAb accepts multiple keyword styles so AI-generated code works without manual edits:

  • function / func / fn / def — all valid
  • let / const — mutable and immutable bindings
  • Semicolons — optional (accepted but not required)
  • return — optional in single-expression functions

NAAb Ecosystem

Three tools built with NAAb — code governance, performance optimization, and data security:

ProjectPurposeKey Features
NAAb BOLOCode governance & validation50+ checks, SARIF reports, AI drift detection
NAAb PivotCode evolution & optimization3-60x speedups, proven correctness, 8 languages
NAAb PassageData gateway & PII protectionZero leakage, sovereign architecture, HIPAA/GDPR

NAAb BOLO — Code Governance & Validation

NAAb BOLO ("Be On the Lookout") catches oversimplified stubs, hallucinated APIs, and incomplete logic in AI-generated code.

# Scan for governance violations
naab bolo.naab scan ./src --profile enterprise

# Generate SARIF report for CI
naab bolo.naab report ./src --format sarif --output results.sarif

# AI governance validation
naab bolo.naab ai-check ./ml-models

50+ checks · 4 languages · 339 regression testsGet started

NAAb Pivot — Code Evolution & Optimization

NAAb Pivot rewrites slow code in faster languages with mathematical proof of correctness.

# Analyze hotspots (Python → Rust candidates)
naab pivot.naab analyze app.py

# Rewrite with proof
naab pivot.naab rewrite app.py:expensive_loop --target rust --prove

# Result: 45x faster, semantically identical

3-60x speedups · 8 source languages · Proven correctGet started

NAAb Passage — Data Gateway & PII Protection

NAAb Passage ensures zero PII leakage to LLMs, APIs, or untrusted systems with sovereign architecture.

# Start secure gateway
naab main.naab

# All requests validated, PII blocked
curl -X POST http://localhost:8091/ -d '{"prompt": "SSN: 123-45-6789"}'
# → {"error": "POLICY_VIOLATION"}

Zero leakage · Self-synthesizing · HIPAA/GDPR compliantGet started


Architecture

Source Code (.naab)
    |
  Lexer ──> Tokens
    |
  Parser ──> AST (recursive descent)
    |
  Governance Engine ──> Policy checks (govern.json)
    |
  ┌─────────────────────────────────────────────┐
  │  Compiler ──> Bytecode ──> VM (default)     │
  │       — OR —                                │
  │  Interpreter (visitor pattern, --tree-walk)  │
  └─────────────────────────────────────────────┘
    |
  ├── Native execution (NAAb code)
  ├── Python executor (C API)
  ├── JavaScript executor (QuickJS)
  ├── Go/Rust/C++/C#/Nim/Zig/Julia executors (compile & run)
  ├── Ruby/PHP executors (interpreted)
  └── Shell executor (subprocess)
  • 120,000+ lines of C++17
  • 396 regression tests, 331 mono test assertions
  • 24 standard library modules with 204 error messages
  • Bytecode VM default (~8x faster), tree-walker via --tree-walk
  • Built with Abseil, fmt, spdlog, nlohmann/json, QuickJS

Contributing

Contributions are welcome! See CONTRIBUTING.md for build instructions and guidelines.

Areas for Contribution

  • VM optimization (src/vm/)
  • Agent governance extensions (src/runtime/governance.cpp)
  • New standard library modules
  • Documentation and tutorials
  • IDE integrations (Vim, Emacs, IntelliJ, VS Code)
  • Package registry (centralized module hosting)

License

MIT License - see LICENSE for details.

Brandon Mackert - @b-macker


NAAb — Polyglot without the trip.