Repository navigation
Releases
IronShell v14.0.1
Full Changelog: v14.0.0...v14.0.1
IronShell v14.0.0
AetherShell is now IronShell. The binary is ish (ae remains as an
alias), the crate iron-shell, the Python SDK ironshell, the editor extension
admercs.ironshell, and the repository nervosys/IronShell (old links redirect).
Scripts use .ish and variables IRONSHELL_*; the old .ae and AETHER_*
names are not read. A security audit on 2026-11-04 reported 13 findings. This
release fixes them, apart from the residual risks the write-up lists; see
SECURITY_AUDIT_2026-11-04.md.
14.0.0 is a major release because calls that used to be quietly accepted now
fail. Every dispatched builtin carries a declared signature, and the dispatcher
holds calls to it: surplus or mistyped arguments, and pipeline input a builtin
does not take, are refused with E_BAD_ARG before anything runs. Builtins that
used to report success without doing the work now say so with a coded error.
Breaking changes
Calls are checked against their declarations.
- Surplus arguments, wrong types and unwanted pipeline input are
E_BAD_ARG.
Before,journal_clear("a")ignored its argument and cleared the whole
journal. - Optional arguments no longer fall back to a default when they are malformed.
Infs_chmod, the string"0"used to mean 0644; it now means mode 0, and a
malformed mode is refused. A malformedfs_chowngroup is refused instead of
being read as the owner. - A pipeline stage's input goes only to that stage. A failing stage stops the
pipeline with an error that names its index and builtin.
Fake successes are now errors. These used to answer as if they had
worked:
sso_authminted a token for any input. It is nowE_UNIMPLEMENTEDand
mints nothing, sosso_validateanswersvalid: false.finetune_start,job_submit, thecloud_*instance builtins,
remote_exec,repl_serve/repl_connect/repl_broadcast,
workspace_sync,plugin_load,marketplace_installand
marketplace_updatereported work that nothing did.compliance_checkandcompliance_reportcalled every standard compliant,
andaudit_verifycalled an empty log valid.agent_with_mcpreported a run that hit its step limit as completed; it is
nowE_BUDGET_EXCEEDED.web_fetch,web_get,web_scrape,web_downloadandweb_uploadfail on
HTTP 4xx and 5xx.web_downloadof a 404 used to answertrue.
Agent-mode policy. Each of these refuses with E_POLICY_DENY or asks for
approval:
- Network: egress needs approval unless
IRONSHELL_NET_ALLOWnames the host
(*restores the old behaviour).ai_backendscharges, and in agent mode
asks approval for, each endpoint it probes. - Clipboard:
clipboard_get,clipboard_get_imageand
clipboard_historyread nothing unlessIRONSHELL_SECRETS=allowor
IRONSHELL_POLICY=permissive. - Undo and redo:
undo,rewind,session_undoandsession_redoleave
a recorded file outside the workspace jail alone. The step stays in the
journal for a human-mode rewind. - Mode variables:
set_env,env_setandenv_unsetcannot change
IRONSHELL_MODE,IRONSHELL_APPROVE_ALLorIRONSHELL_POLICYfrom agent mode. - Commands that imply agent mode:
ish mcp stdio,ish agent executeand
ish agent interactivenow do, asagent serveandmcp servealready did. - Reclassified effects: many builtins changed effect class, which decides
when agent mode asks.rsync_syncis Destructive.helm_install,helm_upgrade,uv_pipandtest_watchare Exec.- Undo, redo,
journal_clearandsession_endare WriteLocal. - The full list is in CHANGELOG.md.
Renamed or reshaped results.
| Builtin | 12.x | 14.0.0 |
|---|---|---|
proc_kill |
true / false |
{pid, signal, sent: true}, or a coded error |
net_latency |
Int | Float (average round trip) |
nanda_quorum |
total_agents |
electorate |
monitor_sockets (Windows) |
foreign_address |
peer_address, as on every OS |
pkg_list |
status, arch fields; rc packages |
{name, version} for installed packages |
proc_list memory (Unix) |
%MEM | bytes, as on Windows |
from_json, JSON readers |
JSON null as the string "null" |
null |
grep |
substring | POSIX basic regular expression |
npm/pnpm/yarn failure |
record with exit_code |
E_TOOL_FAILED with the stderr tail |
docker_logs / k8s logs |
all output | last 1,000 / 200 lines by default |
crypto_cert_info |
openssl's -text output as a String |
an Array with a Record per certificate |
crypto_cert_verify, no trust store |
false |
E_NOT_FOUND |
crypto_generate_key private key |
PKCS#1 or SEC1 PEM from openssl | PKCS#8 PRIVATE KEY PEM; RSA 2048/3072/4096 only; refused under IRONSHELL_FIPS |
Argument shapes.
| 12.x | 14.0.0 |
|---|---|
docker_run("alpine", "echo hi") |
docker_run("alpine", ["echo", "hi"]); likewise docker_exec, the podman twins and k8s_exec |
tmux_new(name, cmd) |
tmux_new(name), then tmux_send |
age_keygen() returned the key |
an output file is required, and no key is returned |
git_checkout("src/app.rs") restored the file |
the name is read as a revision only |
zip_create, scp_download, age, gpg, xz, zstd overwrote outputs |
an existing output is E_BAD_STATE |
Error codes.
E_DECRYPT_UNAUTHENTICATEDis folded intoE_DECRYPT_FAILED(exit 65).E_CRYPTO_FAILED(exit 70) andE_FIPS_DISALLOWED(exit 77) are new.E_OS_DENIED(exit 77) is new: the operating system refused (file
permissions, another user's or a protected process, a privilege not held).
These wereE_POLICY_DENY, which now means only the shell's own policy.
Migration:catch e { if e.error.code == "E_POLICY_DENY" ... }written for
an unreadable file or a foreign process tests"E_OS_DENIED"instead.applyrefuses a plan of more than 10,000 ops (E_BUDGET_EXCEEDED).- A tool stopped at its deadline is
E_BUDGET_EXCEEDED. - An uncaught
throw, or a failingassertused as a statement, ends the
program with exit 1.
Removed.
- The
askalias ofaiwas advertised but never dispatched. Callai. - The fallbacks that quietly used another tool are gone: rg to grep, fd to
find, and yq to a JSON-only evaluator. A missing tool isE_TOOL_MISSING.
Library and SDK.
- The Python SDK's
Agent.runandSwarm.runbuild the same call as the
agentandswarmbuiltins, and raiseValueErrorfor options those cannot
honour. - In the Rust API,
DQNAgent.stepandMultiAgentRL.stepreturnResult.
Migration
- A script that passed extra arguments, or piped into a builtin that ignored the
pipe, now getsE_BAD_ARG. The message names the parameter and prints the
signature, andish agent schemalists every declaration. - Agents that use the network: set
IRONSHELL_NET_ALLOWto the hosts they
need. - Agents that read the clipboard: set
IRONSHELL_SECRETS=allow, or do it in
human mode. - Modifying a SQLite database: use
db_sqlite_exec.sql,sqlite_query
anddb_sqlite_queryare read-only. - Legacy password hashes: Windows SHA-256 hex hashes and Unix SHA-crypt
($5$,$6$) hashes verify, but only outsideIRONSHELL_FIPS, and should be
rehashed after a successful verify. New hashes are Argon2id (PBKDF2 under
IRONSHELL_FIPS). - Python SDK callers: catch
ValueErrorfromAgent.runandSwarm.run.
New in 14.0.0
ish -bruns the ordinary POSIX subset in-process: 32 of 32 byte-identical to
bash on E6, and 32 of 32 on a held-out corpus. Anything else runs through the
effect gate, neverbash -c.- Data access:
- SQL over typed values and files:
sql,sql_valueand a bundled SQLite. open()parses JSON, JSONL, TOML, YAML and CSV, and.fieldrow syntax
works in pipeline stages.
- SQL over typed values and files:
- Agent tooling:
ish --explainandexplain_effects(code)report a call's
effect class and agent decision without running it. - Native builtins:
- Cryptography on IronCrypto (
ironcrypto0.3.2): signing and
verification with Ed25519, deterministic ECDSA P-256 and P-384, and RSA
PKCS#1 v1.5 with SHA-256 (2048 to 4096-bit keys), interoperating with
openssl dgst; key generation (RSA 2048/3072/4096, P-256, Ed25519) as
PKCS#8 PEM; AES-256-GCM envelopes, Argon2id and PBKDF2 password hashes
(compatible with those 12.x wrote); SHA-2, HMAC-SHA-2 and the random bytes
for keys, nonces and salts; and TLS, throughic-rustls. Noopenssl
process outside theopenssl_*wrappers, and ring is not built. - Certificates on IronSocketLayer's X.509 (
ironsocketlayer0.7.1):
crypto_cert_inforeturns a Record per certificate, and
crypto_cert_verifychecks the chain against the system trust store. - Argon2id password hashing (PBKDF2 under
IRONSHELL_FIPS). - TCP sockets with handles.
- Filesystem watch.
- A one-exchange
web_websocket.
- Cryptography on IronCrypto (
- Real scheduling:
cron_*andat_*have working backends. - Linux system administration: accounts, groups, ACLs, mounts, services,
sudo_execand apt. Verified as root in a disposable Debian 13. - Package listing:
pkg_listcovers apt, pacman, rpm (dnf/yum), Homebrew
and Windows Add/Remove Programs. - Windows:
proc_env,proc_cwd,proc_suspendandproc_resume; file ACLs through
icacls; window listing and operations;fs_mount/fs_unmountof VHD and
VHDX files at an NTFS folder;sudo_execin an already-elevated process
(argv only, no shell; batch files refused);lsof(path), the processes
holding a file open, from the Restart Manager. - macOS: services (launchd), accounts and gr...
AetherShell v12.0.2
Full Changelog: v12.0.1...v12.0.2
AetherShell v12.0.1
Full Changelog: v12.0.0...v12.0.1
AetherShell v12.0.0
Full Changelog: v11.0.2...v12.0.0
AetherShell v11.0.2
Full Changelog: v11.0.1...v11.0.2
AetherShell v11.0.1
Full Changelog: v11.0.0...v11.0.1
AetherShell v11.0.0
Full Changelog: v10.1.0...v11.0.0
AetherShell v10.1.0
Full Changelog: v10.0.0...v10.1.0
AetherShell v10.0.0
Full Changelog: v9.0.0...v10.0.0