Repository navigation
Odin v4.12.0
[4.12.0] - 2026-10-01
Upgrade notes
- Local commands now run under bash by default. The new
tools.command_shellsetting (auto,bashorsh,
defaultauto) runs raw model- and skill-written local commands under bash when it is installed. Set
tools.command_shell: shto return to/bin/shat once; new commands pick up the change without a restart. Review
persisted automation (schedules, workflow steps, skillrun_on_hostliterals) for dash-specific syntax before
upgrading. Details are under Changed. - The usage store migrates from schema 3 to 4 on first start, one way. Rolling back to 4.11.0 or earlier switches
usage statistics off (the store itself is left untouched) until you upgrade again. Back updata/usage/before
upgrading if you may roll back. - Open-file headroom. The packaged
odin.servicealready setsLimitNOFILE=65536; installs that run Odin from
their own unit should use equivalent headroom, for example in a drop-in. New in this release, theopen_files
health component reports descriptor use against the soft limit and warns above 70%. - The system prompt lists only usable skills. Disabled skills and skill files that fail to load are no longer
listed in the prompt.list_skills,/api/skillsand the WebUI still show every skill with its status.
Added
- "Stay logged in" survives restarts. Ticked WebUI sessions can survive restarts for up to 30 days, subject to the
configured inactivity timeout. The private session records (data/web_sessions.jsonand a key file, both 0600)
store hashed session ids, identity and source metadata, timestamps, and either an HMAC credential digest or a
dynamic-token issuer fingerprint; no bearer credentials are stored. Unticked sessions stay in memory only, and token
rotation, revocation or logout still end sessions. - Browser waits are configurable per call.
browser_click,browser_fillandbrowser_read_pageaccept an
optionalwait_timeout_seconds(default 10 seconds), clamped to the newbrowser.max_wait_timeout_seconds(default
and hard maximum 60). - Reasoning tokens are recorded for Codex and OpenAI-compatible providers when the provider reports them, in usage
accounting and generation records, and shown beside output tokens on the Usage page. Generations recorded before the
upgrade show as unknown. - Listings show what the model needs.
list_skillsshows each skill's status (loaded, disabled or failed to load)
(#631), andlist_agentsshows each agent's model and effort. - An
open_fileshealth component (see Upgrade notes).
Changed
- Raw local model/skill commands and new background jobs now default to deterministic, non-login
bash when available (tools.command_shell: auto), otherwise sh. The effective local shell appears in
the tool descriptions and is kept in background process records; successful command and skill output is unchanged,
with no shell footer. Explicitbashrefuses before dispatch if unavailable.
Settools.command_shell: shfor immediate compatibility rollback. New jobs
alone use a changed setting; retained records and running-job cleanup keep
their original shell. Remote execution and explicit script interpreters are
unchanged. Code-built internal commands, file/patch transports, script wrappers,
HTTP wrappers and non-command validation probes stay/bin/shwithout shell
annotations. Workflows, schedules, delegated tasks, loops and agents inherit
the setting only through raw command tools. Review persisted automation for
dash-specific syntax before upgrade. - Under bash,
echono longer interprets backslash escapes by default and
echo -eis honoured; useprintffor escapes. Unquoted{a,b}and numeric ranges such as
{1..5}expand, and$'…'decodes ANSI-C escapes. Glob match order follows the locale
(for exampleLANG=en_US.UTF-8), not raw byte order. A failed builtin's$?
can differ: failedcdreturns 2 under dash and 1 under bash. Error wording
usesbash: line 1:rather than/bin/sh: 1:.tools.command_shell: sh
remains the compatibility rollback. - The descriptions of
run_command,run_command_multi,manage_processandvalidate_actionname the effective
local shell in one sentence.manage_processalso says that remote background jobs run under/bin/sh, and the
others that remote commands use the remote account's login shell. - Local command failures report what happened. Timeouts read
Command timed out (exit N), with the signal and
termination reason when known, and localvalidate_actioncommand checks reporttimed out after Ns. Remote
command wording is unchanged. parse_timeaccepts the named clocksnoonandmidnight, and a clock with a day-part phrase such as
8 tonight,this evening at 8or11 in the morning, including supported day words and explicit zones
(8 tonight ET). A day-part phrase alone does not choose a time.midnightmeans the end of the selected day, so
tomorrow at midnightis 00:00 on the day after tomorrow. Contradictions such as8am tonightor
20:00 in the morningare rejected; 4.11.0 accepted some of them with the wrong time.- The
create_skilldescription states the full module contract (aSKILL_DEFINITIONdict and
async def execute(inp, context)) with a minimal example, instead of pointing at template files that are not
shipped (#630).
Fixed
- WebUI tabs return to the sign-in screen when their session ends, for example after a restart, instead of staying on
"Unauthorized/Offline" (#633). - Retained process output no longer holds an open file descriptor per job for 24 hours (#634).
- Changing, regenerating or deleting one API token no longer signs out every other API-token WebUI session, a
regression since 4.11.0. A token's own change still ends its sessions and closes its WebSockets. - "Test skill" in the WebUI runs as the signed-in user, with that user's host access and tier. It previously ran with
no identity, so every host call was refused. - Live Tail reads only the end of the audit log, off the event loop, instead of reading the whole file on every
Logs-page connect. - Removing a host-access entry is audited with the actor, the user id and the previous entry. Removing an absent entry
returns 404 and writes nothing. web_searchtimeouts say the search timed out and after how long, and no error renders an empty message.- Loop history no longer repeats the iteration prefix (
Iteration 2: Iteration 2: …). - The local command supervisor no longer loses ownership of a job when a process vanishes during descendant
discovery, and it detects exits immediately instead of on its next poll. - The command governor recognizes more bash syntax, including ANSI-C quoting (
$'…'), brace expansion and process
substitution. It remains a conservative classifier, not a full shell interpreter. - The WebUI skills page labels skill files that fail to load ("failed to load", with the error) and hides the controls
that cannot work for them. - Native keyboard-focus tests are deterministic (#632).
Commits
v4.11.0..v4.12.0
- bump: v4.12.0 (77d5c2a)
- Merge pull request #635 from Calmingstorm/campaign/v4.12.0 (7290b76)
- fix: simplify shell catalog and filter usable prompt skills (a1efd1d)
- test(auth): align operator reload proof with per-entry issuance (03fddd6)
- fix(auth): preserve sessions for unchanged API token entries (2ffa151)
- test: initialize ownership selector in identity reuse fixture (aa1f592)
- fix: wake shell supervisor on owned process exit (c0a1616)
- test: preserve fail-closed malformed discovery coverage (e7686ad)
- fix: close round-two shell supervision and contract gaps (0f1423a)
- test: settle foreground owners after restoring fixture globals (572d434)
- fix: restore shell compatibility and address PR 635 round one (177d790)
- test: cover shell catalog refresh and recorder identity edges (57c0426)
- fix(shell): restore typed raw transport recovery and opt-in test contracts (d8b16f6)
- test(shell): isolate concurrent kernel shell evidence per invocation (bba435b)
- fix(shell): opt only raw command tools into configured local shell (175b9f2)
- fix(shell): keep internal host transports raw and frame-safe (d74670b)
- fix(core): repair final gate fixtures and compact prompt constraints (db799fc)
- test(web): use real audit files for log admission matrices (531ca7d)
- test(workspace): replace destructive incident replays with cwd proofs (6ba903e)
- test(shell): model verified settlement and unblock worker ACK fixtures (c6f4987)
- fix(governor): bound signed brace range classification (e9b25bc)
- feat(tools): qualify configurable local bash command supervision (60c6462)
- Fix leading daypart timezone extraction (8007f03)
- fix(usage): retain reasoning on incomplete agents and direct chat (c3fd902)
- build(webui): regenerate combined campaign frontend (4eb797e)
- Persist opt-in authenticated WebUI sessions across restarts (ca83123)
- test(computer): own native evidence time across focus fixtures (18ad504)
- test: align scheduling daypart regressions and generated tool reference (5f27541)
- fix: complete model-facing listings, waits, and time grammar (#630, #631) (208f095)
- fix(webui): return expired sessions to sign-in (#633) (f66b508)
- fix(processes): release retained spool descriptors and report file headroom (#634) (a724fd4)
- Fix WebUI skill identity, bounded audit tail and removal history (0a99752)
- feat(usage): persist nullable reasoning tokens across generations (C5) (14b1be8)
- test(computer): stabilize native focus evidence clock (718d677)