* Add hosted single-tenant Postgres profile * Persist hosted extension state under tenant storage * fix(reborn): bound filesystem event tail reads * fix(reborn): reduce hosted postgres read amplification * fix(reborn): batch filesystem thread history reads * fix(filesystem): avoid postgres prefix scans * fix(reborn): harden hosted postgres bootstrap * fix(webui): advance empty projection cursors * fix(reborn): batch llm secret metadata reads * perf(webui): back off idle stream polling * perf(turns): cache fresh filesystem snapshots for reads * fix(reborn): authorize extension lifecycle catalog mounts * fix(reborn): time out wedged turn drivers * fix(reborn): bound stuck heartbeat calls * refactor: split postgres PR hot path helpers * reborn: address hosted postgres review feedback * turns: move test module after production items * reborn: fix hosted postgres review feedback * reborn: fix projection ci regressions * tests: relax reborn harness heartbeat * tests: widen reborn harness heartbeat * ci: harden cargo network fetches * reborn: fix hosted runtime gate diagnostic * tests: wait for budget gate materialization * reborn: fix hosted postgres review and ci issues * reborn: tighten hosted postgres review fixes * reborn: keep nearai bootstrap outcome local * reborn: clarify hosted local-runtime seams * fix(reborn): address CodeRabbit review feedback (#5081) * test(reborn): stabilize runtime no-gateway failure check * fix(ci): update test secret metadata expiry plumbing * fix(threads): make postgres message acceptance atomic * fix(filesystem): retry postgres migration connect * fix(reborn): lower default postgres pool size * fix(reborn): allow postgres pool cap override * fix(filesystem): extend postgres startup retry window * fix(railway): disable reborn deployment overlap * fix(reborn): serve startup health before postgres runtime * fix(reborn): harden startup and inbound accept paths * fix(ci): restore reborn bootstrap build * fix(ci): stabilize reborn harness heartbeat * fix(reborn): collapse repeated auto-approve lookups * fix(reborn): suppress noisy debug logs in hosted serve * fix(reborn): raise hosted-single-tenant postgres pool to 16 The hosted profile shared a single deadpool across every Postgres-backed subsystem (turns, threads, messages, events, secrets), and every filesystem op checks out a connection. With pool_max_size=2 a single turn's reads plus an open transaction monopolize both connections, so the runner heartbeat and webui block indefinitely on pool.get() (no get() timeout), the 90s lease expires, and the turn wedges with failure_category=lease_expired. The cap was lowered to fit a managed session-pool limit during blue-green deploy overlap; that overlap is resolved, so restore a healthy pool (16, the prior default). Runtime override via IRONCLAW_REBORN_POSTGRES_POOL_MAX_SIZE is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * perf(reborn): cache prepared statements + bound postgres pool checkout Two latency/deadlock fixes for the Postgres-backed root filesystem, which backs every Reborn subsystem (turns, threads, messages, events, secrets) and checks out a pooled connection per op. Caching: every fixed-SQL read/write went through `client.query_opt(sql, ..)` with a string, so tokio_postgres issued a fresh `Parse` (prepare) on every call — ~2.77ms RTT to remote Postgres measured from production logs, ~48% of each read, and a monotonically growing set of server-side prepared statements (s1625, s1626, ... never reused). Route the deadpool `Object` (not the deref'd `Client`) through new `cached_query_opt`/`cached_query`/ `cached_query_one`/`cached_execute` helpers that use deadpool's per-connection `prepare_cached`. The Parse round-trip is now paid once per connection per distinct statement; the pooled connection is held for ~half as long per op, which is what relieves the pool contention behind the lease-expiry wedge. Dynamic SQL (filter `query`, index DDL, create_dir_all's txn) stays uncached to keep the cache bounded. Helpers return `tokio_postgres::Error` so existing `db_error` mapping at call sites is unchanged. Deadlock guard: the pool was built with no checkout timeout, so `Pool::get()` blocks forever once all connections are busy — an unbounded wait wedges the runner heartbeat and webui until the 90s lease expires. Add 30s wait/create/recycle timeouts (well under the lease) so a saturated pool surfaces a retryable error instead of hanging the process. Verified: `cargo clippy` clean and `cargo check` pass for ironclaw_filesystem, ironclaw_reborn_event_store, and ironclaw_reborn_composition with postgres[,webui-v2-beta]. Live Postgres behavior + latency delta verified via PR CI and Railway (no local live-pg test / Docker). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(reborn): size hosted postgres pool for the Supabase pooler (10) The reference hosted deployment fronts Postgres with the Supabase Supavisor session pooler (default pool size ~15), so the shared app pool must stay under that cap. 16 could exceed it; 10 covers runtime concurrency (heartbeat, webui, trigger poller, turn driver reads + open txn) with headroom for migrations and admin sessions. Runtime override IRONCLAW_REBORN_POSTGRES_POOL_MAX_SIZE still wins over this file. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
27 KiB
ironclaw-reborn standalone binary
ironclaw-reborn is the standalone executable boundary for Reborn. It is separate from the current ironclaw binary so Reborn boot, config, state, and runtime composition can evolve without accidentally invoking v1 runtime paths.
This binary is available as the workspace package ironclaw_reborn_cli and builds the executable named ironclaw-reborn.
Current status
ironclaw-reborn is an early operator/testing surface, not the default IronClaw runtime.
It currently supports:
ironclaw-reborn --help
ironclaw-reborn channels list
ironclaw-reborn channels list --json
ironclaw-reborn channels list --verbose
ironclaw-reborn completion --shell bash
ironclaw-reborn completion --shell zsh
ironclaw-reborn config path
ironclaw-reborn doctor
ironclaw-reborn extension search github
ironclaw-reborn extension search github --json
ironclaw-reborn extension install github-mcp
ironclaw-reborn extension activate github-mcp
ironclaw-reborn extension remove github-mcp
ironclaw-reborn hooks list
ironclaw-reborn hooks list --json
ironclaw-reborn hooks list --verbose
ironclaw-reborn logs
ironclaw-reborn logs --json
ironclaw-reborn logs --verbose
ironclaw-reborn models list
ironclaw-reborn models list --json
ironclaw-reborn models status
ironclaw-reborn models status --json
ironclaw-reborn models set-provider openai --model gpt-5-mini
ironclaw-reborn onboard
ironclaw-reborn onboard --dry-run
ironclaw-reborn onboard --force
ironclaw-reborn onboard --import-history # flag parsed, but history import not wired yet
ironclaw-reborn profile list
ironclaw-reborn profile list --json
ironclaw-reborn repl
ironclaw-reborn run
ironclaw-reborn run --confirm-host-access
ironclaw-reborn serve # only compiled in with --features webui-v2-beta
ironclaw-reborn serve --confirm-host-access
ironclaw-reborn skills list
ironclaw-reborn skills list --json
ironclaw-reborn skills list --verbose
The traces command tree is a contributor-only trace client; see
crates/ironclaw_reborn_cli/src/commands/traces/ for its subcommands.
It intentionally does not yet support:
- replacing
ironclawbehavior; - daemon/service installation;
- v1 config, DB, settings, or secrets migration;
- production extension/tool execution;
- long-lived Reborn runtime services.
The WebChat v2 web UI is supported through serve, but only when the
binary is built with --features webui-v2-beta. The serve subcommand is
compiled behind that feature, so without it serve does not exist in the binary
at all — it will not appear in --help and ironclaw-reborn serve errors as an
unknown subcommand. It is an early beta operator surface, not a production
gateway. See Running with the WebUI (serve).
Running with the WebUI (serve)
serve starts the WebChat v2 HTTP listener so you can drive Reborn from a
browser. This is the fastest way to exercise the full loop (ingress → turn
runner → LLM provider → timeline) end to end.
Shortcut: scripts/run-reborn-webui.sh wraps the steps below — it keeps the
Reborn home outside the repo, configures the route, generates the WebUI token,
and launches serve. Export your provider key first, then run it:
export NEARAI_API_KEY=... # or OPENAI_API_KEY / ANTHROPIC_API_KEY
scripts/run-reborn-webui.sh # NEAR AI default
PROVIDER=openai scripts/run-reborn-webui.sh
It prints the login token and the http://127.0.0.1:3000/v2 URL. Override
PROVIDER, MODEL, REBORN_HOST, REBORN_PORT, or IRONCLAW_REBORN_HOME via
the environment. The manual steps below are equivalent.
Quick start
# 1. For serve/run/repl the Reborn home must live OUTSIDE your current working
# directory: these commands use the cwd as the local-dev workspace root and
# reject overlap with it (see gotchas). Other commands have no such rule.
export IRONCLAW_REBORN_HOME="$HOME/.ironclaw-reborn-demo"
# 2. Configure a model route. NEAR AI shown here; swap the provider id and key
# env var for any row in the table below. set-provider records the credential
# env-var NAME in config.toml; the secret VALUE stays in the environment.
cargo run -q -p ironclaw_reborn_cli --features webui-v2-beta --bin ironclaw-reborn -- \
models set-provider nearai
export NEARAI_API_KEY="your-key-here"
# 3. WebUI auth. serve REQUIRES both values or it refuses to start. The variable
# NAMES below are the defaults; override them via [webui].env_token_var and
# [webui].env_user_id_var in config.toml if you prefer different names.
export IRONCLAW_REBORN_WEBUI_TOKEN="$(openssl rand -hex 32)" # bearer token you log in with
export IRONCLAW_REBORN_WEBUI_USER_ID="reborn-cli" # must match [identity].default_owner
# 4. Launch (feature flag is mandatory — the UI is not compiled in without it).
cargo run -q -p ironclaw_reborn_cli --features webui-v2-beta --bin ironclaw-reborn -- serve
Then open http://127.0.0.1:3000/v2 and log in with the
IRONCLAW_REBORN_WEBUI_TOKEN value.
--host / --port override the defaults (127.0.0.1 / 3000), or set
[webui].listen_host / [webui].listen_port in config.toml. --port 0
(the CLI flag only) tells the OS to pick a free ephemeral port — useful for
test harnesses, though the banner still prints :0. [webui].listen_port = 0
in config.toml is rejected, since a config-driven ephemeral port is almost
always a mistake. For the Slack host-beta ingress, build with
--features slack-v2-host-beta (it includes webui-v2-beta).
Choose your model provider
models set-provider <id> works for any provider in the built-in catalog. For
API-key providers it records that provider's credential env-var name in
config.toml for you; for keyless providers (e.g. ollama) it writes no
api_key_env. The common single-API-key providers:
| Provider | set-provider id |
Key env var | Default model |
|---|---|---|---|
| NEAR AI | nearai |
NEARAI_API_KEY |
deepseek-ai/DeepSeek-V4-Flash |
| OpenAI | openai |
OPENAI_API_KEY |
gpt-5-mini |
| Anthropic | anthropic |
ANTHROPIC_API_KEY |
claude-sonnet-4-20250514 |
| Ollama (local) | ollama |
(none — runs locally) | llama3 |
So to use Anthropic instead of the quick-start example, swap step 2 for:
cargo run -q -p ironclaw_reborn_cli --features webui-v2-beta --bin ironclaw-reborn -- \
models set-provider anthropic
export ANTHROPIC_API_KEY="your-key-here"
Not sure which env var your chosen provider needs? After set-provider, run
models status — it prints default.api_key_env (the exact variable to
export) alongside the active provider and model. models list --verbose shows
the same for every provider in the catalog, including whether its key is
required or optional; pass --model <id> to set-provider to override the
default model. Providers that use OAuth or multi-field credentials (bedrock,
gemini_oauth, openai_codex) need extra setup beyond a single key.
Missing keys are fatal for required-key providers. For api_key_required
providers (openai, anthropic, and most others), run/serve/repl exit at
startup during LLM resolution with llm provider '<id>' requires API key env var '<VAR>' to be set if the env var is missing. For no-key providers (ollama)
and NEAR AI's session flow (api_key_required: false), the runtime boots
without that env var and authenticates separately — so export your provider's
key before launching serve.
Common startup errors (and fixes)
These are validation failures that abort serve before it binds; each prints a
single-line Error: and exits.
| Error message contains | Cause | Fix |
|---|---|---|
must be set to the WebChat v2 bearer token |
IRONCLAW_REBORN_WEBUI_TOKEN unset |
Export the token env var (step 3). |
must be set to the UserId an env-bearer-authenticated caller maps to |
IRONCLAW_REBORN_WEBUI_USER_ID unset |
Export the user-id env var (step 3). |
default_owner ... must match the WebChat v2 authenticated user |
[identity].default_owner ≠ IRONCLAW_REBORN_WEBUI_USER_ID |
Set the env user to the config owner (default reborn-cli), or remove/align [identity].default_owner. |
workspace root must not overlap default skill root /skills |
Reborn home is inside the current working directory | Point IRONCLAW_REBORN_HOME at a path outside your repo/cwd. |
The workspace-overlap one is the easiest to trip: serve/run/repl use the
current working directory as the local-dev workspace root, and boot is
rejected if that root overlaps any default storage root Reborn manages —
/skills (<reborn-home>/local-dev/skills), /tenant-shared/skills,
/system/skills, or /system/extensions. If the home is nested inside the cwd
(e.g. IRONCLAW_REBORN_HOME="$PWD/.reborn-home"), those roots fall under the
workspace root and boot is rejected. Keep the home outside the directory you
launch from — the default ~/.ironclaw/reborn already satisfies this.
(Resolved per-user skills live under
<reborn-home>/local-dev/tenants/default/users/<owner>/skills; the flat
local-dev/skills is a legacy root that is backfilled into that tenant-scoped
path. The validation above guards the legacy/default roots, which is why the
error names /skills.)
Smoke-test a turn over the API
The browser UI talks to the /api/webchat/v2 routes. You can drive the same
loop with curl to confirm the model route works without opening a browser:
TOKEN="$IRONCLAW_REBORN_WEBUI_TOKEN"
BASE=http://127.0.0.1:3000/api/webchat/v2
AUTH="Authorization: Bearer $TOKEN"
# create a thread -> returns .thread.thread_id
TID=$(curl -s -X POST "$BASE/threads" -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"client_action_id":"smoke-1"}' \
| python3 -c "import sys,json;print(json.load(sys.stdin)['thread']['thread_id'])")
# send a message -> queues a turn
curl -s -X POST "$BASE/threads/$TID/messages" -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"client_action_id":"smoke-msg-1","content":"Reply with exactly: NEARAI_OK"}'
# read the timeline. Turn execution is async, so re-run this until an
# assistant message with status "finalized" appears (usually a second or two).
curl -s "$BASE/threads/$TID/timeline" -H "$AUTH" | python3 -m json.tool
A healthy run shows a kind: "assistant", status: "finalized" message in
messages[] with the model's reply (the first read right after sending may
still show only the user message — repeat the timeline request until it
finalizes). GET /api/health returns
{"status":"healthy","channel":"reborn"} and /v2 serves the UI; / is
intentionally a 404. CORS is fail-closed with no allowed origins, so drive it
from a browser on the same host against 127.0.0.1.
Commands
channels list
Reports configured Reborn channels without resolving Reborn home, reading v1 channel config, or creating directories.
The Reborn channel registry is not wired yet, so the command currently reports an explicit empty surface:
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- channels list
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- channels list --json
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- channels list --verbose
Expected fields include:
configured: 0status: not-wiredv1_state: not-used
extension
Searches and manages local-dev Reborn extensions through the same lifecycle facade exposed to product surfaces. Available extension packages are read from /system/extensions, which maps to <reborn-home>/local-dev/system/extensions for the local-dev profile.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- extension search github
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- extension search github --json
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- extension install github-mcp
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- extension activate github-mcp
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- extension remove github-mcp
The commands are scoped to Reborn boot/config resolution and do not create or read v1 state directories.
Expected fields include:
phasepackage_ref.idfor package-specific commandspayload.kindpayload.countandpayload.extensions[].package_ref.idfor searchpayload.installed,payload.activated, orpayload.removedfor lifecycle mutations
completion
Generates shell completion scripts without resolving Reborn home, reading v1 state, or creating directories.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- completion --shell zsh > ironclaw-reborn.zsh
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- completion --shell bash > ironclaw-reborn.bash
The zsh output keeps the v1 CLI guard around compdef so the generated script is safe when zsh completion functions are not loaded yet.
config path
Shows the resolved Reborn state root, its source, selected profile, and explicit v1-state status without creating directories.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- config path
Expected fields include:
reborn_homehome_sourceprofilev1_state: not-used
config path, doctor, and other read-only surfaces do not create Reborn
state or seed config files.
doctor
Validates and reports Reborn boot configuration without creating state directories or starting runtime services.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- doctor
Expected fields include:
reborn_homehome_sourceprofilev1_state: not-useddriver_registry: initialized
hooks list
Reports configured Reborn hooks without resolving Reborn home, reading v1 hook config, or creating directories.
The Reborn hook registry is not wired yet, so the command currently reports an explicit empty surface:
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- hooks list
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- hooks list --json
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- hooks list --verbose
Expected fields include:
configured: 0status: not-wiredv1_state: not-used
logs
Reports Reborn log availability without resolving Reborn home, reading v1 gateway logs, or creating directories.
The Reborn log source is not wired yet, so the command currently reports an explicit empty surface:
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- logs
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- logs --json
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- logs --verbose
Expected fields include:
entries: 0status: not-wiredv1_state: not-used
onboard
First-run bootstrap for the standalone Reborn home. It resolves
IRONCLAW_REBORN_HOME (or the default ~/.ironclaw/reborn), creates the home
directory, writes missing config.toml and providers.json using the same
atomic writer as config init, preserves operator-edited files unless
--force is passed, writes a .onboard-completed.json marker, and prints the
remaining setup work. It does not call into v1 src/setup, v1 database
config, v1 channels, or v1 import state.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- onboard
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- onboard --dry-run
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- onboard --force
--dry-run reports what would be initialized without writing files.
--import-history reserves the history-import step in the summary (not wired
yet). See docs/reborn/onboarding.md for the full slice description and the
completion-marker schema.
models list / models status / models set-provider
Shows Reborn model purpose slots and route status, and configures the default LLM route.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- models list
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- models list --json
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- models status
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- models status --json
models status reports the configured default route, including the exact env
var to export for it — handy for confirming setup before serve/run:
default.providerdefault.provider_known(yesonce the provider id resolves in the catalog)default.modeldefault.api_key_env(the env var that must hold your key, e.g.NEARAI_API_KEY)default.base_url(only when the route configures one)v1_state: not-used
Those are the text field names. models status --json serializes the
selection struct instead, nesting the route under default with the raw field
names: provider_id (not provider), provider_known, model, api_key_env,
and base_url.
models list prints the full provider catalog, marks the active provider with
*, and (with --verbose) shows each provider's api_key_env, default model,
and credential kind.
models set-provider <provider> [--model <model>] writes [llm.default] into
$IRONCLAW_REBORN_HOME/config.toml with the provider id and, for API-key
providers, its catalog credential env-var name (keyless providers like ollama
get no api_key_env). <provider> is a provider id or alias (openai,
anthropic, nearai, ollama, …); --model is optional and defaults to the
provider's catalog default.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- models set-provider openai --model gpt-5-mini
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- models set-provider nearai --model deepseek-ai/DeepSeek-V4-Flash
The secret value still lives in the environment under the catalog's
api_key_env (e.g. OPENAI_API_KEY, NEARAI_API_KEY); set-provider only
records the variable name, never the value. Once [llm.default] exists it
selects the provider; LLM_BACKEND is only an env fallback when no default slot
is configured.
profile list
Lists the supported Reborn boot profiles without resolving Reborn home, reading v1 state, or creating directories.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- profile list
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- profile list --json
Supported profiles:
local-dev(default)local-dev-yoloproductionmigration-dry-run
Select a profile with IRONCLAW_REBORN_PROFILE=<profile>.
run
Starts the standalone Reborn runtime and reads messages from stdin. The no-profile path targets the planned AgentLoop runtime (reborn-planned-default). Without model provider environment variables, the runtime still starts but messages fail cleanly because no LLM gateway is wired.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- run
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- run --message "hello"
Use --dry-run for the side-effect-free readiness snapshot:
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- run --dry-run
When $IRONCLAW_REBORN_HOME/config.toml is missing, the first stateful
runtime start through run, repl, or feature-gated serve seeds a sparse
config.toml containing api_version and the safe local-dev boot profile.
It intentionally does not seed [llm.default], so env-only model selection
continues to work. run --dry-run, diagnostics, and read-only commands remain
side-effect-free. One-off environment selections such as
IRONCLAW_REBORN_PROFILE=local-dev-yolo are not persisted into the seeded
file.
Expected fields include:
binary: ironclaw-rebornversionreborn_homehome_sourceprofilev1_state: not-usedruntime_driver: planned-agent-loopdriver_registry: initializedlocal_runtime_shell_readiness: readyplanned_default_profile: available
For IRONCLAW_REBORN_PROFILE=local-dev-yolo, run, repl, and serve require --confirm-host-access before the runtime receives trusted-laptop host access. Confirmed access mounts the host home through /host; Unix-style raw home aliases are also accepted when they can be represented as scoped mount aliases.
When serve --confirm-host-access grants trusted-laptop access, serve refuses non-loopback listeners such as 0.0.0.0. Bind to 127.0.0.1 or ::1, or use a less privileged profile for non-loopback test listeners.
For IRONCLAW_REBORN_PROFILE=production, run requires production storage
and an explicit runtime policy:
[storage]
backend = "postgres"
url_env = "IRONCLAW_REBORN_POSTGRES_URL"
secret_master_key_env = "IRONCLAW_REBORN_SECRET_MASTER_KEY"
# Optional; defaults to 2. Keep below the PostgreSQL server or managed
# session-pool cap after reserving capacity for restarts and operator sessions.
pool_max_size = 2
[policy]
deployment_mode = "hosted_multi_tenant"
default_profile = "secure_default"
Set IRONCLAW_REBORN_POSTGRES_URL in the process environment, and set
IRONCLAW_REBORN_SECRET_MASTER_KEY to independent cryptographic key material.
Remote managed PostgreSQL URLs must use TLS, for example sslmode=require.
Set IRONCLAW_REBORN_POSTGRES_POOL_MAX_SIZE to override the configured pool
size when a managed provider enforces a smaller session-pool cap.
The first production launch slice supports runtime policies that do not require
a tenant-sandbox process binding.
repl
Starts an interactive Reborn session backed by the composed runtime, reading
turns from stdin. Same runtime as run, without the WebUI listener. Accepts
--confirm-host-access for local-dev-yolo.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- repl
serve
Starts the WebChat v2 HTTP listener (browser UI). Requires a binary built with
--features webui-v2-beta and the two IRONCLAW_REBORN_WEBUI_* auth env vars.
See Running with the WebUI (serve) for the
full walkthrough, auth setup, common startup errors, and an API smoke test.
cargo run -q -p ironclaw_reborn_cli --features webui-v2-beta --bin ironclaw-reborn -- serve
cargo run -q -p ironclaw_reborn_cli --features webui-v2-beta --bin ironclaw-reborn -- serve --host 127.0.0.1 --port 3000
skills list
Reports configured Reborn local-dev skills from <reborn-home>/local-dev/skills
and <reborn-home>/local-dev/system/skills through the Reborn composition
skill listing function. It does not read v1 skill discovery paths, and a missing
local-dev storage root is reported as an empty skill list without creating
directories.
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- skills list
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- skills list --json
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- skills list --verbose
Expected fields include:
configured: <count>source: reborn-local-dev- per-skill
name,source, anddescriptionin text output - per-skill
name,version,description,source,keywords,tags, andrequires_skillsin JSON output
--verbose adds the resolved profile, reborn_home, local_dev_root, and
owner_id; text output also includes per-skill version, keywords, tags,
and requires_skills when present. skills list currently supports
local-dev and local-dev-yolo profiles and rejects production /
migration-dry-run until those catalog backends are wired.
State and config root
Reborn must not use the current v1 IronClaw state root by default.
Home resolution precedence:
IRONCLAW_REBORN_HOME~/.ironclaw/reborn
The resolver rejects unsafe or misleading homes, including empty paths, relative paths, filesystem root, parent-directory components, and known v1 state-root aliases such as $HOME/.ironclaw or IRONCLAW_BASE_DIR.
Profiles
Use IRONCLAW_REBORN_PROFILE to select the boot profile.
Supported values:
local-dev(default)local-dev-yoloproductionmigration-dry-run
Example:
IRONCLAW_REBORN_HOME="$PWD/.reborn-home" \
IRONCLAW_REBORN_PROFILE=production \
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- doctor
Local smoke checks
Run these before changing Reborn CLI behavior:
cargo fmt --all -- --check
cargo test -p ironclaw_reborn_cli
cargo test -p ironclaw_reborn_config
cargo test -p ironclaw_reborn model_slots_are_exposed_in_cli_display_order
cargo test -p ironclaw_architecture reborn
cargo clippy -p ironclaw_reborn_cli --all-targets -- -D warnings
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- --help
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- channels list
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- completion --shell zsh >/tmp/ironclaw-reborn.zsh
IRONCLAW_REBORN_HOME="$(mktemp -d)/reborn-home" \
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- config path
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- hooks list
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- logs
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- models status
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- profile list
IRONCLAW_REBORN_HOME="$(mktemp -d)/reborn-home" \
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- run
cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- skills list
Adding commands
Future commands should follow the crate-local agent contract in:
crates/ironclaw_reborn_cli/AGENTS.md
Short version:
- add one command module under
crates/ironclaw_reborn_cli/src/commands/; - register it in
commands::Command; - resolve and pass
RebornCliContextfrom dispatch only when the command needs boot config; - keep pure commands independent from Reborn home resolution;
- add a binary smoke test through
env!("CARGO_BIN_EXE_ironclaw-reborn"); - avoid v1 runtime imports and v1 state mutation unless explicitly scoped and guarded.
Do not port the current src/cli/* command tree wholesale. Port commands one at a time, starting with Reborn-owned or read-only surfaces.
Release packaging decision
ironclaw-reborn is not yet included in cargo-dist release artifacts.
Current dist plan --output-format=json with crates/ironclaw_reborn_cli marked dist = false emits only the root ironclaw package artifacts. Removing dist = false alone is not enough to ship ironclaw-reborn in the existing ironclaw-v* release workflow because that workflow is shaped around the root ironclaw package tag. Enabling a standalone ironclaw_reborn_cli release also requires cargo-dist WiX metadata/template work and an explicit tag/versioning decision.
Follow-up issue: #3483 tracks packaging ironclaw-reborn in release artifacts.
Until #3483 is resolved, keep:
[package.metadata.dist]
dist = false
in crates/ironclaw_reborn_cli/Cargo.toml so releases do not silently claim to ship an unverified Reborn binary package.