Skip to main content

Reliability for LLM agents through enforcement, not model size — Agent-Contract-Kernel (ACK) + a fail-closed orchestration engine.

Project description

Ironclad

CI PyPI License: Apache-2.0 Python Status

An agent loop you run yourself — and a development process that turns a one-line idea into a finished product.

You say what you want. "A fast CLI to search files" is enough. From there the agents pin down what you actually mean, weigh the architecture, split the work into units, and write the code with its tests — on your hardware, with any open model, no cloud subscription and no vendor holding the off switch.

The bet behind the project is simple: a small model kept on a short leash beats a big one you merely trust. Ironclad supplies the leash. Every tool call is checked against a schema and retried until it's valid; the mechanical file work runs as plain code, not as something the model has to remember to do. Reliability comes from the contract, not the parameter count — which is exactly why you can swap the model whenever you like.

How the loop works

At the core is an ordinary agent loop, with two things bolted on that make it dependable instead of merely clever: a contract kernel that refuses malformed tool calls, and a memory that gets better the more the loop runs.

flowchart LR
    A(["💬 You describe<br/>what you want"]):::idea --> B["🧠 Agent decides<br/>the next step"]:::step
    B --> C{"🛠️ Tool call"}:::review
    C -->|"schema-checked"| D["▶️ Run it<br/><i>file · shell · search · panel</i>"]:::step
    C -->|"malformed"| B
    D --> E["↩️ Result back<br/>to the model"]:::step
    E --> B
    B -->|"done"| F(["✅ Answer<br/>or delivered work"]):::done
    D -.->|"learns from<br/>every run"| G[("📚 Playbook<br/>ACE")]:::mpr
    G -.->|"informs"| B
    classDef idea fill:#e0e7ff,stroke:#6366f1,color:#1e1b4b,stroke-width:2px
    classDef step fill:#f8fafc,stroke:#94a3b8,color:#1e293b,stroke-width:1.5px
    classDef mpr fill:#ede9fe,stroke:#8b5cf6,color:#4c1d95,stroke-width:2px
    classDef review fill:#fef3c7,stroke:#f59e0b,color:#78350f,stroke-width:2px
    classDef done fill:#d1fae5,stroke:#10b981,color:#065f46,stroke-width:2px

A plain question ("what is 17 × 23?") just runs the loop once and answers. Real work — anything that produces files, a design, a plan — runs the same loop but under a process that keeps it honest.

From an idea to a product

The part most agent tools skip is everything before the code: deciding what "done" means, choosing the architecture on purpose instead of by accident, and making sure the plan actually covers what you asked for. Ironclad puts that in the open, under /project.

flowchart TD
    P(["💬 a one-line idea"]):::idea
    P --> S["📋 Scope<br/><i>the agent asks, you approve</i>"]:::step
    S --> M["⚖️ Design panel<br/><i>7 lenses weigh the architecture</i>"]:::mpr
    M --> D["🧭 Design<br/><i>one proposal + trade-offs</i>"]:::step
    D --> RV{"🔍 Review"}:::review
    RV -->|"findings → revise"| D
    RV -->|"clean"| U["🧩 /plan<br/><i>epic + every unit, scope-checked</i>"]:::step
    U -->|"/auto on<br/><i>review on (default)</i>"| B["✋ Approved-plan boundary<br/><i>marker saved · hard exit</i>"]:::review
    B -->|"/auto on again<br/><i>optional: /approve plan</i>"| R["⚙️ Drain<br/><i>coders write &amp; test each unit</i>"]:::step
    U -.->|"/auto on<br/><i>review off: single run</i>"| R
    R --> X(["🎯 a working product"]):::done
    classDef idea fill:#e0e7ff,stroke:#6366f1,color:#1e1b4b,stroke-width:2px
    classDef step fill:#f8fafc,stroke:#94a3b8,color:#1e293b,stroke-width:1.5px
    classDef mpr fill:#ede9fe,stroke:#8b5cf6,color:#4c1d95,stroke-width:2px
    classDef review fill:#fef3c7,stroke:#f59e0b,color:#78350f,stroke-width:2px
    classDef done fill:#d1fae5,stroke:#10b981,color:#065f46,stroke-width:2px
    linkStyle default stroke:#94a3b8,stroke-width:1.5px

Here's what that looked like on a real run. The prompt was three words of intent, a fast file-search CLI. The agent didn't just start typing. It elicited a scope (recursive content search, ignore-file handling, stdout/stderr separation, and so on) and had you approve it. Then, instead of asserting a language out of nowhere, a multi-perspective panel scored the choice across performance, security, maintainability, ops, reversibility, team-fit and cost and recommended Rust with Go kept as the honest runner-up. An architecture-tier external coder wrote the single design from that recommendation, with trade-offs and dissent left in the document. A reviewer read the design back and found real gaps; those fed into a revision the review signed off before anything was approved. From the approved design the agent produced one epic and every implementation unit, each tied to the scope items it covers, and the coders built them.

You stay in the loop at the points that matter — approving the scope, approving the design, and optionally confirming the review-clean decomposition with /approve plan — while the engine drives the authoring turns in between. The plan confirmation reports stale design or unit bindings but is not another automation gate. With design and decomposition review on (the default), the first /auto on drives planning to the approved-plan boundary, saves a marker, and hard-exits with an operator notice. Re-run /auto to drain implementation to a closed epic. With review off, one /auto on can run end to end; leave it off and the engine recommends the next step and waits for you.

There's a full walkthrough in docs/nordstar.md: the same weak prompt, start to finish, with the artefacts it leaves behind.

Quickstart

git clone https://github.com/GrokBuildMJW/ironclad.git && cd ironclad
pip install -e ".[engine]"
export GX10_BASE_URL=http://localhost:8000/v1 GX10_MODEL=your-model

python engine/server.py &              # the orchestrator: the agent + its state
python engine/client.py --codedir .    # the client: drives it, keeps your code local

Then, in the client:

/project new demo          # a workspace; artefacts live under vault/<slug>/
Read README.md and summarise it.
Build add(a,b) in calc.py with a pytest test, and run it.

The orchestrator holds the agent and the state; the client runs on your machine and keeps your code there — the agent's file and shell tools are handed back to the client and execute against your local files, never a copy on a server. Anything that leaves artefacts behind needs an active project first; a plain question doesn't. That's deliberate: without a project the macros refuse rather than scatter state through your working directory.

What's under the hood

The loop above is the product. Underneath it, a few pieces do the heavy lifting:

  • A contract kernel (ACK) — one Pydantic schema per task drives the prompt, the validator and the docs, and recovers tool calls from models that can't emit them natively.
  • A design review panel and strong-coder author — the bundled multi-perspective reasoner (MPR) scores an architecture decision across expert lenses, including an advisory simplicity/operability advocate; the configured complex coder class authors the proposal, receives one deterministic complexity self-review, and then enters independent review and revision.
  • Loop Intelligence (ACE) — an always-on memory that distils each run into an itemised playbook and feeds it back into later runs. No flag to turn it on; it's how the loop improves.
  • End-of-run self-verification — every completed turn reads its active project's durable artifacts back, checks the managed board, degraded-round cause, and review-round counters without another model call, and turns any finding into the failed outcome the client renders.
  • Scalable context — a bounded model window with a rolling summary and long-term vector(+graph) retrieval, so long sessions don't fall over.
  • Governed parallelism — server-side reasoning fan-out under a concurrency cap and a token budget, with optional routing across providers.
  • A plugin surface — drop a tool into a skills/ directory and the agent picks it up, no core fork; a versioned plugin API and a bring-your-own coding-agent CLI keep the extension contract stable.

Point it at a regional open model — Falcon, Jais, K2 Think over vLLM (running on other models) — and you get the same fail-closed pipelines and structured tool calls without retraining anything.

Honest status

The engine comes from an orchestrator that was already running in production; it's been rebuilt into the server + client shape above, wired and tested, and it's still early — currently v0.0.32, single-tenant by design, with one operator and no multi-user auth yet. The APIs and layout can still move. Releases ship on PyPI (ironclad-ai) and as GitHub Releases; treat main as a development snapshot.

The claims here are backed by automated tests and a full end-to-end run with a real coding agent. Before you rely on anything, read:

Setup

You need Python 3.10+ and any OpenAI-compatible endpoint (vLLM, for example).

pip install ironclad-ai                  # ACK library only (import ack)

# For a runnable engine, clone the repository, then choose one:
pip install -e ".[engine]"               # engine source + declared runtime dependencies
bash install/ironclad-install.sh         # full setup; Windows: install\ironclad-install.ps1

The full walkthrough — the server/client split, the reference vLLM launch, and copy-paste shortcuts for PowerShell, macOS and Linux — is in SETUP.md. If you'd rather have an AI coding agent set it up, AGENTS.md is a deterministic runbook.

Developed on an NVIDIA DGX Spark (GB10, 128 GB unified memory) running vLLM with Qwen3.6-35B-A3B; nothing is wired to that box, but the defaults reflect it. Reasoning fan-out over 8 prompts runs about 5.8× faster than serial there. See docs/dgx-spark.md.

Extend it

Ironclad is a foundation, not a finished product. Domain use cases dock on as vessels — a runnable example lives in examples/demo-vessel/, and a generator scaffolds new ones — so you build reliable, self-hosted agents for your field instead of starting from scratch. Building in your own repo? pip install ironclad-ai and import the Extension SDK (ack.sdk) to ship plugins against a versioned surface. The framework even maintains itself: its own agents scaffold new plugins, and a dev container runs the full suite as a build gate.

Layout

ack/               agent-contract kernel: schema, validated emit, registry, doctor, generator
engine/            orchestration engine: the agent loop, task store, fail-closed macros
clients/ink/       recommended TypeScript terminal client (build from source)
examples/          runnable example workspace
docs/              guides, ADRs, Apache-2.0

At runtime, engine machinery hides under .ironclad/ and every artefact lives under vault/<slug>/, so your project root stays clean — see docs/project-isolation.md.

License

Apache 2.0 — see LICENSE and NOTICE. Copyright 2026 MJWC-AI-LAB and Ironclad contributors. Built in the United Arab Emirates.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ironclad_ai-0.0.32.tar.gz (187.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ironclad_ai-0.0.32-py3-none-any.whl (216.4 kB view details)

Uploaded Python 3

File details

Details for the file ironclad_ai-0.0.32.tar.gz.

File metadata

  • Download URL: ironclad_ai-0.0.32.tar.gz
  • Upload date:
  • Size: 187.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ironclad_ai-0.0.32.tar.gz
Algorithm Hash digest
SHA256 594f518969e4ad8bb1f165cee8e63eeef5b61d36d7ff790c93bd5ee0421d467b
MD5 35f504de887c8d6d099e6db4fd7afd16
BLAKE2b-256 0834501c642d38f0e68db514bf9e03f411be11acee3175dd4a1670b0c2839a18

See more details on using hashes here.

Provenance

The following attestation bundles were made for ironclad_ai-0.0.32.tar.gz:

Publisher: publish.yml on GrokBuildMJW/ironclad

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ironclad_ai-0.0.32-py3-none-any.whl.

File metadata

  • Download URL: ironclad_ai-0.0.32-py3-none-any.whl
  • Upload date:
  • Size: 216.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ironclad_ai-0.0.32-py3-none-any.whl
Algorithm Hash digest
SHA256 31100ee8f8fdaa5d66b43d6c3e42c13403bd5cecf024cc3b274facaa1d8cdca9
MD5 940a491bbf5ee5000b6f0ceb5c5c6c41
BLAKE2b-256 c7fe9ef6555ce51fd60e631c7c632cc36b34ed5489eaaba5032f6bde324a2eec

See more details on using hashes here.

Provenance

The following attestation bundles were made for ironclad_ai-0.0.32-py3-none-any.whl:

Publisher: publish.yml on GrokBuildMJW/ironclad

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page