unreasonably simple software engineering

Software engineering is an exercise in assembling categories of services.

Every new capability means a new system to learn, configure, deploy, and monitor. The complexity of actual integrations is quadratic — overwhelming for devs and for AI context.

iii fundamentally eliminates this complexity and makes it linear.

And we ship integrations the same way node ships packages so using a new service is as easy as importing a new library.

get started
§ 00 · EXPERIENCE

any task. one experience.
iii makes it unreasonably efficient to create and extend software.

Slack Messages

any service. one abstraction.
The answer to "we need X" stops being "evaluate, procure, integrate." It becomes: add a worker.

any language. one protocol. python registers a function. rust registers a function. node consumes both.

Node.js Worker
orchestrator
01
import { registerWorker, Logger } from "iii-sdk"

const iii = registerWorker(
  "ws://localhost:49134"
)
const logger = new Logger()

const nums = await iii.trigger({
  function_id: "data::transform",
  payload: [1.0, 2.0, 3.0],
}) // → [2.0, 4.0, 6.0]

const pred = await iii.trigger({
  function_id: "ml::predict",
  payload: { data: nums },
}) // → { predictions: […] }

logger.info(pred) // ml::predict → { predictions: [0.91, 0.07, 0.02] }
Rust Worker
data transform
02
use iii_sdk::{
    register_worker, IIIError,
    Value,
};
use serde_json::json;

async fn transform(
    input: Value,
) -> Result<Value, IIIError> {
    let nums: Vec<f64> =
        serde_json::from_value(input)?;
    let result: Vec<f64> =
        nums.iter().map(|x| x * 2.0).collect();
    Ok(json!(result))
}

#[tokio::main]
async fn main() -> Result<(), IIIError> {
    let iii = register_worker(
        "ws://localhost:49134",
        InitOptions::default(),
    )?;
    iii.register_function(
        "data::transform",
        transform,
    );
    Ok(())
}
Python Worker
ML inference
03
import torch
from iii import register_worker

iii = register_worker("ws://localhost:49134")

async def predict(input):
    t = torch.tensor(input["data"])
    result = model(t)
    return {
        "predictions": result.tolist()
    }

iii.register_function(
    "ml::predict", predict
)
step 1 / 7 — node triggers data::transform
step 1/7

any agent. one system.
agents aren't a new category of infrastructure. they're just workers — same protocol, same trace, same engine.

any log. one context.
a system you and your agents can see from end to end.

01 / 09 · workers
workers 10/10 internal · refresh
all 10 node 3 rust 4 python 2 go 1
planner node 0.11.3 127.0.0.1 · pid 252 · 4 fn · 1m ago
tool-runner rust 0.11.3 127.0.0.1 · pid 95970 · 11 fn · 3 active · 1m ago
embed-worker python 0.11.0 127.0.0.1 · pid 218 · 3 fn · 1m ago
iii-lsp rust 0.1.0 127.0.0.1 · pid 28041 · 2 fn · 1m ago
content-router node 0.11.3 127.0.0.1 · pid 14872 · 5 fn · 2 active · 2m ago
iii-state rust 0.11.3 10.0.0.4 · pid 4421 · 6 fn · 4m ago
iii-durable rust 0.11.3 10.0.0.4 · pid 4422 · 8 fn · 5 active · 4m ago
content-classifier python 0.11.0 10.0.0.7 · pid 9128 · 2 fn · 6m ago
billing-svc go 0.11.0 10.0.0.9 · pid 7203 · 4 fn · 7m ago
notify-bridge node 0.11.3 10.0.0.11 · pid 6610 · 3 fn · 8m ago

every worker — across runtimes — discovered as it connects.

functions 38 system · refresh
▾ agent 5 functions
</>agent::plan
</>agent::run_tools
</>agent::synthesize
</>agent::critique
</>agent::reflect
▾ tools 6 functions
</>tools::web_search
</>tools::code_exec
</>tools::browse
</>tools::fetch
</>tools::file_io
</>tools::shell
▾ memory 4 functions
</>memory::recall
</>memory::store
</>memory::embed
</>memory::search
▾ content 4 functions
</>content::classify
</>content::route
</>content::on-flagged
</>content::publish
▾ state 4 functions
</>state::get
</>state::set
</>state::delete
</>state::scan
▾ durable 3 functions
</>durable::publish
</>durable::subscribe
</>durable::ack
▾ billing 4 functions
</>billing::charge
</>billing::refund
</>billing::usage
</>billing::invoice
▾ notify 3 functions
</>notify::email
</>notify::slack
</>notify::webhook
▾ iii 5 functions
</>iii::on_functions_available
</>iii::on_worker_connect
</>iii::trace::open
</>iii::log
</>iii::heartbeat

every function — every language — invokable from one place.

triggers 12 all 12 http 5 event 5 cron 2
▾ http 5 triggers
POST /agent/run
agent::plan
http
POST /content/submit
content::route
http
POST /billing/charge
billing::charge
http
GET /memory/search
memory::search
http
POST /webhooks/stripe
notify::webhook
http
▾ event 5 triggers
tool::completed
agent::synthesize
event
plan::ready
agent::run_tools
event
content::flagged
content::on-flagged
event
billing::charged
notify::email
event
worker::connected
iii::on_worker_connect
event
▾ cron 2 triggers
every 5m
iii::heartbeat
cron
0 0 * * *
billing::invoice
cron

http, events, cron, websockets — every entrypoint, one schema.

states key-value store 7 groups refresh
agent42
memory128
session31
moderation87
billing54
config19
cache364
key ↑typepreview
plan_p_7f3ajson{ steps: 4, …}⎘ ✕
plan_p_88e1json{ steps: 7, …}⎘ ✕
plan_p_a1c4json{ steps: 3, …}⎘ ✕
token_countnumber148,209⎘ ✕
last_querystring"research iii…"⎘ ✕
flags:u_4188number3⎘ ✕
flags:u_9920number1⎘ ✕
embed_indexvector[1024d × 8,420]⎘ ✕
session:s_be12json{ user: "u_4188", …}⎘ ✕
cache:web:opentel…blob14.2 KB⎘ ✕

durable state — namespaced, typed, observable.

streams websocket monitor pause · export · clear · system
2,418 messages 1,892 inbound 526 outbound size: 184 kb ws://127.0.0.1:3113/ws/streams
all ↘ inbound ↗ outbound
12:38:01.030disconnected{"message":"WebSocket connection closed"}
12:38:00.020connected{"message":"WebSocket connection established","url":"ws://127.0.0.1:3113/ws/streams"}
12:37:59.823disconnected{"message":"agent::token","token":"primitives"}
12:37:55.819connected{"message":"agent::token","token":"composable"}
12:37:52.805disconnected{"message":"agent::token","token":"runtime"}
12:37:49.798connected{"message":"tool::web_search","query":"opentelemetry"}
12:37:46.794connected{"message":"agent::step","idx":2}
12:37:42.602connected{"message":"content::flagged","author":"u_4188","score":0.91}
12:37:39.118connected{"message":"billing::charged","amount":2400,"customer":"c_8821"}
12:37:35.482connected{"message":"memory::store","key":"emb:3f02","bytes":4096}
12:37:31.227connected{"message":"notify::email","to":"alex@motia.dev","template":"flagged"}
12:37:28.014connected{"message":"durable::publish","topic":"comment.publish","seq":18420}
12:37:24.901connected{"message":"worker::heartbeat","worker":"tool-runner","load":0.42}

live websocket bus — agent tokens, tool calls, status, in real time.

queues 9 topics 12 subscribers refresh
tool-calls durable 142 pending · 38 in-flight · 2 dead
plan-events fanout 12 pending · 9 in-flight · 0 dead
embed-batch durable 821 pending · 64 in-flight · 4 dead
comment.publish durable 48 pending · 21 in-flight · 0 dead
comment.review durable 204 pending · 12 in-flight · 1 dead
billing.charge durable 6 pending · 3 in-flight · 0 dead
notify.email fanout 88 pending · 14 in-flight · 0 dead
notify.slack fanout 2 pending · 1 in-flight · 0 dead
memory.index durable 312 pending · 28 in-flight · 0 dead

named queues — backpressure & retries, native to the protocol.

traces 1,847 system · pause · refresh
POST /agent/run
e08ff04 · 1.95ms · ⎇
plan
run_tools
web_search
code_exec
synthesize
12:38:36
POST /content/submit
4cda981 · 8.42ms · ⎇
route
classify
publish
notify
12:38:32
iii::on_functions_available
b92fbded · 2.28ms
12:38:30
POST /billing/charge
71f084a · 14.21ms · ⎇
charge
state::set
notify::email
12:38:24
tools::web_search
709bb22b · 2.71ms
12:38:16
memory::search
3e78c2f · 42.18ms
embed
vector::knn
12:38:08
memory::store
aa521adb · 2.40ms
12:37:50
tools::code_exec
5f631ce1 · 1.06ms
12:37:48
notify::webhook
9b211ce · 502 · 3.04s
timeout
12:37:14
agent::synthesize
2ce92e90 · 1.46ms
12:36:50

opentelemetry, native — every span across every language, one trace.

›_logs 14,208/14,208 pause · export · clear
time ▾ all severities ▾ 11,402 2,612 184 10
12:38:35.302221e521…iiinew functions detected, firing functions-available trigger
12:38:34.821billing-svccharge succeeded customer=c_8821 amount=2400
12:38:33.114notify-bridgedelivered notify::email → alex@motia.dev
12:38:32.402content-routerclassifier latency p99=842ms (budget 600ms)
12:38:16.336iii[REGISTERED] Endpoint POST /agent/runagent::plan
12:38:16.336iii[REGISTERED] Function tools::web_search
12:38:16.335iiiWorker registered tool-runner (rust)
12:38:14.610iiiWorker registered billing-svc (go)
12:38:14.610iiitool-runner reconnect attempt 1
12:38:13.815iii[UNREGISTERED] Function tools::web_search
12:38:08.219embed-workerindexed batch 0e8f2a · vectors=512 · 184ms
12:37:39.3028a682f6a…iiiFunction not found: agent::critique
12:37:14.022notify-bridgewebhook 502 stripe.com — retry queued (3/5)
12:37:18.3017e0703f4…iiitools::code_exec called in Python with q="2+2"
12:36:54.594iiinew functions detected, firing functions-available trigger
12:36:52.567iii[REGISTERED] Function iii.on_functions_available

structured logs — protocol-native, severity-coded, trace-linked.

configuration 10/10 healthy view config · export · system · refresh
10workers
38functions
12triggers
9queues
725state keys
2,418stream msgs
1,847traces
10healthy
iii engine
REST API & DevTools
http://127.0.0.1:3113/api/engine
streams
websocket streams
ws://127.0.0.1:3113/ws/streams
sdk bridge
worker connections
ws://localhost:49134
traces
otel collector
grpc://127.0.0.1:4317
state store
durable kv
tcp://10.0.0.4:7521
queue broker
durable topics
tcp://10.0.0.4:7522
embed index
vector store
tcp://10.0.0.7:6333
billing
payment gateway
https://10.0.0.9:8080
notify bridge
email · slack · webhook
https://10.0.0.11:8081
auth
jwt · oidc
https://auth.iii.local
trigger types 10
http"http"
event"event"
cron"cron"
state"state"
stream::join"stream::join"
stream::leave"stream::leave"
subscribe"subscribe"
queue"queue"
webhook"webhook"
log"log"
worker pools 4
rust4connected workers
node3connected workers
python2connected workers
go1connected workers

the system at a glance — every primitive, healthy and addressable.

iii in a nutshell. every capability, every framework, and every tool become a pattern on the same core system.

execution model — how iii runs work. durable, interoperable, simple.

01 / 06

durable orchestration

coordinate long-running, failure-tolerant execution across workers and triggers.

02 / 06

interoperable execution

execute across languages natively, as if it were one runtime.

03 / 06

simple primitives

collapse distributed backend design into a paradigm humans and agents can reason about.

live system traits — what iii becomes once running. discoverable, extensible, observable.

04 / 06

live discovery

functions and triggers exposed by one worker become visible across the system in real time.

05 / 06

live extensibility

add new workers and capabilities to a live iii system without redesigning the architecture.

06 / 06

live observability

observe operations, traces, and behavior across the entire connected stack in real time.