iii-core-primitives
Use when registering iii functions, binding triggers, selecting sync/void/enqueue invocation, creating workers, inspecting the live worker registry, installing…
Use when composing iii primitives into backend architectures: durable workflows, reactive backends, agentic pipelines, event-driven CQRS, effect pipelines, and trigger-transform-action automation.
$ npx -y skills add iii-hq/iii --skill iii-architecture-patterns --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/iii-architecture-patternsContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when composing iii primitives into backend architectures: durable workflows, reactive backends, agentic pipelines, event-driven CQRS, effect pipelines, and trigger-transform-action automation.
name: iii-architecture-patterns description: >- Use when composing iii primitives into backend architectures: durable workflows, reactive backends, agentic pipelines, event-driven CQRS, effect pipelines, and trigger-transform-action automation.
Use this skill when the task is larger than one function or trigger. Pick the pattern from the requirement, then implement it with `Function`, `Trigger`, `Worker`, state, queues, streams, and pub/sub.
| Requirement | Pattern | iii shape | | --- | --- | --- | | Sequential work with retries, DLQ, step tracking | Durable workflow | Functions chained through named queues, progress in state | | Keep views, metrics, cache, or clients in sync | Reactive backend | State triggers plus stream/pubsub side effects | | Specialized AI agents hand work to each other | Agentic backend | One function per agent, queue handoffs, shared state | | Commands publish events and projections update independently | Event-driven CQRS | Command functions, event log in state, subscribe triggers | | Pure, traceable composition | Effect pipeline | Small functions composed synchronously with `trigger()` | | Webhook/cron automation chains | Low-code automation | Trigger, transform, action nodes chained by enqueue |
Use named queues when steps need different retry, FIFO, or concurrency policy.
import { registerWorker, TriggerAction } from "iii-sdk";
const iii = registerWorker("ws://localhost:49134", { workerName: "order-workflow" });
async function track(orderId: string, step: string, status: string) {
await iii.trigger({
function_id: "state::update",
payload: { scope: "orders", key: orderId, ops: [{ op: "set", path: `/steps/${step}`, value: status }] },
});
}
iii.registerFunction("orders::validate", async (order) => {
await track(order.id, "validate", "done");
return iii.trigger({
function_id: "orders::charge",
payload: order,
action: TriggerAction.Enqueue({ queue: "order-payment" }),
});
});
iii.registerFunction("orders::charge", async (order) => {
await track(order.id, "payment", "done");
return iii.trigger({
function_id: "orders::ship",
payload: order,
action: TriggerAction.Enqueue({ queue: "order-ship" }),
});
});from iii import register_worker
iii = register_worker("ws://localhost:49134")
def track(order_id, step, status):
iii.trigger({
"function_id": "state::update",
"payload": {
"scope": "orders",
"key": order_id,
"ops": [{"op": "set", "path": f"/steps/{step}", "value": status}],
},
})
def validate(order):
track(order["id"], "validate", "done")
return iii.trigger({
"function_id": "orders::charge",
"payload": order,
"action": {"type": "enqueue", "queue": "order-payment"},
})
iii.register_function("orders::validate", validate)use iii_sdk::TriggerAction;
use iii_sdk::protocol::TriggerRequest;
use serde_json::json;
async fn enqueue_charge(iii: iii_sdk::IIIClient, order: serde_json::Value) -> Result<serde_json::Value, iii_sdk::Error> {
iii.trigger(TriggerRequest {
function_id: "state::update".into(),
payload: json!({
"scope": "orders",
"key": order["id"],
"ops": [{ "op": "set", "path": "/steps/validate", "value": "done" }]
}),
action: None,
timeout_ms: None,
}).await?;
iii.trigger(TriggerRequest {
function_id: "orders::charge".into(),
payload: order,
action: Some(TriggerAction::Enqueue { queue: "order-payment".into() }),
timeout_ms: None,
}).await
}Use state triggers when the requirement says "after create/update, do this", "avoid polling", or "push live updates".
iii.registerFunction("todos::on-change", async (event) => {
await iii.trigger({
function_id: "stream::send",
payload: { stream_name: "todos-live", group_id: "default", data: event.new_value },
action: TriggerAction.Void(),
});
});
iii.registerTrigger({
type: "state",
function_id: "todos::on-change",
config: { scope: "todos" },
});Model each agent as a function with one responsibility. Store shared context in state and hand off work through named queues.
iii.registerFunction("agents::researcher", async (task) => {
await iii.trigger({
function_id: "state::set",
payload: { scope: "research", key: task.id, value: { findings: [] } },
});
return iii.trigger({
function_id: "agents::critic",
payload: task,
action: TriggerAction.Enqueue({ queue: "agent-tasks" }),
});
});Commands validate and publish domain events. Projections subscribe independently and write query-optimized state.
iii.registerFunction("cmd::add-inventory-item", async (input) => {
const event = { type: "inventory.item-added", itemId: input.itemId, quantity: input.quantity };
await iii.trigger({
function_id: "state::set",
payload: { scope: "inventory-events", key: `${Date.now()}-${input.itemId}`, value: event },
});
await iii.trigger({ function_id: "publish", payload: { topic: event.type, data: event } });
return { accepted: true };
});
iii.registerTrigger({
type: "subscribe",
function_id: "proj::inventory-list",
config: { topic: "inventory.item-added" },
});What is iii? · Quick Start · Add Workers · SDKs · Agent Skills · Console · Resources
Repo: iii-hq/iii
Use when registering iii functions, binding triggers, selecting sync/void/enqueue invocation, creating workers, inspecting the live worker registry, installing…
Configure a managed iii engine through worker-compose.yaml or a directly supervised engine through config.yaml. Use for engine ports, RBAC listeners, streams,…
Handle iii engine and SDK errors across Node, Python, Rust, and browser workers. Use when interpreting error codes, retryability, RBAC denial, timeouts,…
Install the iii engine, set up your first worker, and get a working backend running. Use when a user wants to start a new iii project, install the SDK, or…
Use when working with iii SDK APIs across Node.js, browser, Python, or Rust: package installation, worker initialization, function/trigger registration,…
Turn a tech-spec directory into an interactive, marketing-grade web presentation — built so engineers understand the design, the reader is convinced of the…