Releases: GrokBuildMJW/ironclad
Release list
v0.0.32 β design-review convergence
Ironclad v0.0.32
Design reviews now converge. This release rebuilds the design-review lifecycle end to end: reviewers
return structured findings tracked in a durable ledger, blocking findings close only on evidence from
an independent verifier, and deterministic pre-checks run before any paid review round. A simplicity
budget, convergence loop control with checkpoints, governed operator recovery, and strong-author
routing machinery complete the picture β plus a large set of reliability fixes found in live testing.
Added
- Design reviews now converge: structured, typed findings reconcile into one durable ledger per design; approval requires no active blocking finding.
- Evidence-based closure: a blocking finding closes only when an independent verifier (different agent and model) confirms the fix; fail-closed until a third identity is configured.
- Deterministic pre-checks before paid review (schema, placeholders, concurrency, traceability, complexity budget) with versioned, expiring, audited waivers.
- Simplicity budget: non-standard primitives must be justified at authoring time; a cheap deterministic advisory pass flags complexity before review.
- Loop control with checkpoints: convergence stops when nothing blocks, detects stalls and oscillation, and rolls back to the best checkpoint on exhaustion.
- Governed recovery:
/recoverycommands let operators override eligible medium/low findings with cooldowns, expiry, and an immutable audit trail. - Strong-author routing validation harness (offline replay, hash-pinned suite, independent audit sidecar); machinery only, no quantitative routing claim.
- Strong-coder scope and design authoring by default (inline-mode opt-out), with an engine-enforced implementation-spine decision before any scope is recorded.
- Design-to-scope conformance declarations required before review; scopes must declare elicitation defaults, concrete standards, and reasoned requirement-altering assumptions.
- Durable provenance and verification: author/prompt stamps, a per-turn write manifest, artifact verification at run end, and design validation on write.
- Maintainer-only scripted drive of the front-half lifecycle, durably marked as fabricated.
Changed
- Built-in OPUS agent defaults to Claude Opus 5; the review cost envelope accumulates across escalations.
- Coder launches go through one typed lane; Kimi Code 0.29.1 compatibility and a legacy-CLI guard; reviser/author jobs launch read-only.
- Ink: copying wrapped text stays complete across line boundaries;
/approve scoperenders readable itemized rows. - README and test report no longer publish platform-dependent suite counts.
Fixed
- Live-testing reliability fixes for the new review lifecycle: pre-check retries no longer drop findings, finished author jobs settle, blocked/exhausted states tell the truth and the next step.
- Front-half automation: project switches deliberately disarm it, support tasks no longer stop it, cancellation recovers cleanly.
- One authoritative design lineage (a replacement proposal cancels the old running review); escalated review remediates terminal findings before paying for re-review.
- Review/reviser failures carry stable machine-readable causes across restarts; task-board rows are bounded and injection-safe.
- Reviser output is validated before persistence under a dedicated size limit; reviewer findings re-enter prompts fenced as untrusted content.
- Review round counting and cost accounting are monotonic and survive degraded runs.
- Vault reconciliation and the lineage graph now include review artifacts; autopilot names the agent that ran; spine reasoning is no longer silently truncated.
- Pre-release public-export audit fixes and an explicit security gate listing for
/sessionand/turns.
v0.0.31 β front-half delegation + pre-release audit
Added
-
Installer efficiency and Ink dependency hygiene (#1832): unchanged dependency payloads are reusable, the client replaces the deprecated
license-checkerchain withlicensee, the reviewed install-script allowlist covers esbuild and optional macOS fsevents for flows that permit lifecycle scripts, and the high-severity audit finding is resolved. -
Push-visible front-half review lifecycle (#1836): background design/plan review and convergence progress is now visible live in the Ink client β review-job launches, outcomes, and converge rounds surface as they happen (via the guarded
GET /eventsfeed) instead of only at the end of a turn. -
Phase-aware automation (#1827):
/autonow drives planning only up to the current approved plan, saves a boundary marker, and hard-exits with an operator notice to re-run/autofor execution; a re-plan creates a fresh boundary, and the staging/launch gate refuses an armed, un-exited boundary. -
The planning-to-execution hard-stop applies when design/decomposition review is enabled (the default); with review off, no approved-plan boundary forms and
/autoruns end-to-end. -
Watcher-driven front-half convergence (#1821-c/d):
/designand/plannow run their review rounds as board-visible background jobs and return PENDING while the watcher resumes reviewer, meta-reviewer, and reviser work independently for every design variant. Retries and restarts are safe (no duplicated rounds or lost feedback), anddesign_review.async_converge=falsekeeps the synchronous fallback. -
Durable front-half convergence state (#1821-a): design and decomposition review loops now persist their resumable round, cost, verdict, and artifact history under
.work/converge/so review work survives restarts. -
Decomposition confirmation:
/approve plan [--anyway]confirms a review-clean current R-B result, reports disabled review as stageable, and re-invalidates stale design/unit bindings without adding a manual staging gate or overriding HARD findings. -
Escalated front-half review:
/escalate reviewgives a HARD-blocked design or decomposition a fresh, default-four-round strong-coder convergence run without weakening approval or staging gates. -
Engine-owned lifecycle finding categories, fail-closed HARD/SOFT classification, deterministic artifact HARD checks, and idempotent accepted-review notes on design proposals and decomposition epics.
-
Front-half lifecycle convergence:
/designand/plannow review, strongly revise, and re-review drafts before returning, with model-distinct reviewers, engine-owned persistence, bounded TERMINAL findings, and loud DEGRADED failures. -
Per-invocation lifecycle cost envelope:
/designand/plannow estimate configured coder spend across review, meta-review, and revision calls against the default-$100design_review.cost_envelope_usdbackstop. -
Model-distinct lifecycle meta-review: R-A and R-B APPROVE verdicts now require a different-model reviewer-of-review, with authoritative blindspot findings and loud fail-closed meta unavailability.
-
Guided approved-design decomposition (#1794):
/plantriggers the one-epic-plus-all-units turn, fail-closed until scope+design are approved. -
Durable turn/action observability (#1790): every tool dispatch appends a redacted JSONL record to
turns.jsonl; new/turnsand/sessionHTTP readers expose it. -
Panel-led approvable designs (#1779):
design_review.modecan make the MPR decision panel an automatic pre-/designarchitecture/language gate. -
Front-half armed continuation (#1777, #1827): armed
/autodrives planning autonomously to the approved plan, hard-exits there, and drains implementation only after the operator re-runs/auto. -
Per-project live config overlays (#1778):
/config setvalues apply immediately and persist as a project-scoped overlay surviving/switchand restart. -
Durable direct-continuation forensics (#1745): silent continuation-tick exits, deferrals, and authoring-turn outcomes now write structured, deduplicated audit records.
-
Durable run observability (#1750, #1781): headless server retains a sanitized, size-rotated console log and archives bounded coder logs per run.
-
ACE learning-loop quality (#1748, #1751): near-duplicate lessons fold honestly by identifier/polarity, and retrieval keeps a reserved slot for proven lessons.
-
Engine-derived handover run records (#1752): handovers get an idempotent
## Run recordwith runtime facts and a precision-first tool-availability evidence gate. -
Active-initiative control-plane write jail (#1742 trust surface, #1743): a fail-closed guard refuses model file-tool mutation of the active initiative's control-plane directories.
-
Durable epic completion report and real poll transport (#1749, #1754; Slice 2): epic auto-close assembles an atomic, engine-stamped completion report with a durable
/healthpointer. -
Retroactive P2 notice activation (#1749, #1758, #1753): design-review-unavailable and code-review-skip notices now reach the real
/healthpoll transport, best-effort. -
Engine-stamped epic reconciliation records (#1754, #1749; Slice 1): epic auto-close writes a bounded, atomic reconciliation record of unreferenced required scope ids.
-
Handover internal-consistency gate (#1744): staging refuses a handover whose file is both forbidden-to-modify and required-to-modify by the same task.
-
Default-on, premise-free automatic code review (#1753, #1648):
code_review.modenow defaults tosimple, running one bounded reviewer pass per advanced unit. -
Design and decomposition review stages (#1758, slices 1β3): adds default-on, fail-closed R-A/R-B lifecycle review with engine-stamped, per-target evidence artifacts.
-
Design/decomposition review final remediation (#1758): closes gate gaps across create/claim/next-task launch seams and binds R-B approval to the unit-content hash.
-
Product-scope foundations (#1755):
record_scope//approve scopeadd a validated, versionedscope.mdartifact gating epics on approved, closed scope. -
Configurable automatic code-review stage in the dev-loop (#1614): an optional per-unit reviewer gate (
code_review.mode) blocks non-approved units until they pass or exhaust rounds.
Changed
- Board-visible front-half coder work (#1821-b): lifecycle reviewers, model-distinct meta-reviewers,
and strong-coder revisers now run as detachedreview-jobtasks through the shared handover/feedback
machinery while the convergence loop still waits synchronously. Review jobs remain board-visible but
are excluded from implementation-unit selection, continuation, and reconciliation; every synchronous
dispatch terminates even when its feedback is blocked or times out. - UTF-8 external-coder stdio (#1822): the synchronous CLI runner now decodes coder stdout and stderr
explicitly as UTF-8 with replacement for malformed bytes, independent of the host platform locale. - Canonical planning command (#1810):
/planis now the advertised decomposition verb; operator guidance names exact scope, design, planning, automation, and handover commands. - Design/decomposition convergence now stops when no HARD findings remain; SOFT findings are surfaced without revision, capped HARD findings are blocked, and
/approve design --anywaycannot override them. - Bounded front-half spend: reaching the lifecycle USD envelope after a reviewed round stops with the last residual findings as TERMINAL; exhaustion before any verdict is loud DEGRADED, and results plus durable evidence expose estimated spend and the envelope.
- Strong-coder front-half authoring: qwen remains the initial design/decomposition drafter, but an unscored MPR design is re-authored once and all HARD review findings are revised by an architecture-tier coder; qwen never reviews or revises.
- Canonical project command (#1800):
/initiativeis retired from the visible surface, kept only as a silent alias for/project.
Removed
- Obsolete weak front-half revise stage: full automation now waits at
/approve designafter internal strong-coder convergence instead of enqueueing a second qwen revision;/plan_unitsremains a silent back-compat alias.
Fixed
- Reviser stream-output normalization (#1852): design/plan revisions produced by streaming coders
(Kimi message streams, Claude stream-json) are now correctly extracted into the saved artifact instead of
occasionally persisting empty or transcript-polluted output. Stream-shaped output with no extractable answer
logs a warning and falls back to the cleaned raw response instead of a silent empty artifact. - Durable, fail-closed front-half convergence (#1840): asynchronous design/decomposition reviews now
survive restarts β interrupted review work resumes from its last consistent checkpoint or restarts cleanly
rather than re-running the whole loop (a narrow crash window may repay at most one already-finished review)
and never promotes unreviewed work. Unreadable or inconsistent review state ends in a
loud DEGRADED refusal rather than silently proceeding. - Public export and release-prep correctness: public docs now use repository-root paths and match the
server's guarded route surface; export rewriting also handles top-level paths without a trailing slash
without collapsing historical move descriptions. The README's deterministic current-version marker is
restored so the README,docs/status.md, andpyproject.tomlversion stamps stay mutually consistent
across a release cut. - Workspace-scoped project listing (#1838):
/project listnow shows only the projects in your current
workspace instead of every project ever registered;/project list --allstill exposes the complete
installation-global registry with workspace labels. Unresolvable project roots fail safe (they can narrow the
scoped vie...
v0.0.30 β always-on protections + full robustness audit
An early preview. main is a development snapshot; treat releases as previews.
Highlights
Protections are always-on and secure-by-default. A repo-wide audit of every config-switchable function established the principle a protection mechanism must not be switchable, and made the guarantees non-optional:
- Design β build lifecycle, completion authority, coder authorization + audit ledger, the untrusted-result injection fence, and the OS execution sandbox (bwrap/firejail on Linux) are mandatory and fail-closed β not switchable off.
- Secure deployment defaults: fresh servers bind loopback under the unauthenticated profile and refuse non-loopback exposure without explicit auth; search/forge default off; connection/coder timeouts are finite and ceiling-bounded.
- Typed config schema + transactional
/config set(clone β validate β derive β commit-or-rollback), a generated config reference, and a documented-switch/read-switch parity guard so a raw config gate outside the typed accessor fails CI. - Build-boundary egress tripwire (advisory supply-chain signal driven by the approved design's network posture).
A full-Ironclad robustness audit hardened ten defects across the engine and the terminal client:
- Whole process-tree termination for model commands and coder launches on timeout/cancel; a hard per-coder wall-clock; bounded model-facing filesystem I/O and Ink output capture.
- Atomic skill-catalogue install and transactional multi-file generation (no data-loss on a failed write); fail-closed MPR evidence retention with verified deletion.
- Tool-result delivery that resends independent of the reconnect edge; a serialized, seal-on-stop session heartbeat;
/updateruns executable+argv without a shell and validates its source path.
See the CHANGELOG for the full list.
Install: pip install ironclad-ai==0.0.30
v0.0.29 β constraint reframe + tooling envelope
Fixed
- Proposals-with-trade-offs S5 follow-up (#1418):
/design --options [N]now warns when the model records
fewer proposal files than requested, no longer claims trade-offs were validated in the confirmation text,
and has negative coverage for fail-closed argument, active-unit, and missing-agent paths. - Tooling envelope FA follow-up (#1420): DEV-1 now authorizes every configured CLI provider/code-agent
launch tuple plus the default non-stream autopilot tuple, runtime gates share the same inherited-default
canonical launch tuple as registry filtering, and Ink treats an absent server-shipped policy as
default-off to match Python handover parity. - Constraint reframe follow-up (#1413): fixed the M5
/forkproposal list call after the product
constraint-fork retirement, removed stale ink/approve constraint,/dismiss constraint, and
/fork decidehelp/autocomplete surface, and hardened the ink parity guard against stale server verbs
and retired usage tokens.
Changed
- Constraint reframe S1 (#1414/#1413): retired the product operator constraint gate, typed HARD-floor
readers, product constraint-fork ledger,/approve constraint,/dismiss constraint, and the
constraint-envelope ACE leg.record_constraintsnow writes optional non-gating framing notes under
notes/framing.md; it no longer writesdecisions/constraints.mdor revokes/blocks approved designs. - Design lifecycle S3 (#1416/#1413):
record_designnow retains non-destructive
proposals/design-<n>.mdvariants,/approve design [<id>]promotes one approved decision, later
re-records no longer auto-revoke the approved decision, and## Build policyis carried on promote and
injected with the approved design standard. - Build enforcement now rests on the approved design standard:
_design_build_checkremains, reads
_design_typed, and usesack.ace.constraint_conflict.hardcheck;normalize_languageis retained for
design metadata. The shared_ACE_FORK_WORKERand M5 architecture-fork/forkproposal surface remain. - DEV-1 config now leaves
constraint_gate.enabledandsafety.constraint_conflict_detectoff by default
for the retired product paths while keepingdesign_gate.enabledand the M5-only
ace.fork_mpr.enabledon.
Added
- Proposals-with-trade-offs S5 (#1418/#1413):
/design --options [N]is a deterministic
operator-triggered design fan-out behinddesign_gate.enabled. It accepts N in the enforced 2..8 range
and defaults to 2, then asks the model to record Nproposals/design-<n>.mdvariants through the existing
record_designpath, each with a## Trade-offspros/cons section; the operator promotes the chosen
proposal with/approve design <id>. With the gate off, the command refuses before a model turn or file
write. - #1420 completes the ADR-0007 tooling-envelope FA: a default-off
security.tooling_envelope.enabledpolicy with{bin, cmd_template}allow-list loading, the pure
ack.tooling_envelope.assert_authorizedhelper, strict fail-closed malformed-input handling, exact
realpath identity for pinned executables, basename-only matching for bare commands, portable*/?
globbing, ASCII-whitespace command-template normalization, and shared Python/Ink parity vectors for
$VAR/${VAR}plus bare-~expansion while leaving undefined env references,%VAR%,~user, and
bracket classes literal. Enforcement is wired at every coder-spawn lane: provider CLI fan-out/web-search
runner, Python handover using the server-shipped policy, autopilotlaunch_coder, reconciler launch
queue,review,/coders use, provider/code-agent registry filtering, and the TypeScript handover
client./pendingcarries only the non-secret effective allow-list for local client spawn checks,
envelope-on CLI refusal is terminal instead of spilling to in-engine fan-out, and FA-S3 adds the
per-lane test matrix plus docs for BYO code-agent operators. Public installs remain byte-identical while
the policy is off;GX10_TOOLING_ENVELOPE_ENABLEDmirrors the nested config toggle.
v0.0.28 β constraint compliance, reasoning-runaway resilience, DEV-1 live-test fixes
Ironclad v0.0.28 β constraint compliance, reasoning-runaway resilience, and DEV-1 live-test fixes.
Highlights
Constraint compliance (L1/L2/L3). An operator-stated language/network constraint is now an engine-visible, enforceable floor end-to-end: captured (incl. a best-effort capture-completeness gate that refuses a prose-only constraint whose typed field is omitted), surfaced per turn, and fail-closed hard-checked at design approval + implementation handover. A deviation goes through an operator-owned fork with an MPR decision-matrix recommendation β never a silent override. keep/counter leave a coherent, approvable state, and the fork decision is surfaced as a concrete, ready-to-run /fork decide <id> --choice keep|counter command.
Reasoning-runaway resilience. A first-token-decoupled LLM timeout so a legitimate large-context prefill is no longer killed by the shared read timeout; a phase-aware idle watchdog; opt-in resumable partial-persist on a stream wedge; and an opt-in salvage of a blank reasoning-runaway into one bounded no-think answer.
Operator-flow fixes. The terminal client no longer lets a locally-launched code-agent write into the client's own terminal (coder output goes to files); a code-agent launch is guarded against a retired CLI model and a failed coder is surfaced instead of silently stalling.
All new behavior is default-off / byte-identical unless explicitly enabled. See CHANGELOG.md for the full list.
v0.0.27 β design-driven autonomous continuation (plan_units + /auto), client freeze fix
Added
- Design-driven autonomous continuation β an approved design now drains to done end-to-end. Previously a
design-driven project stopped after its first task: the post-advance planner could only continue from a
configured capability backlog, and with none it silently disarmed itself β nothing ever staged the next
unit. Three pieces close the loop:plan_units(new macro): after design approval, ONE call materializes the FULL decomposition β one
epictask (new ACKTaskType.EPIC) plus ALL implementation units as pending tasks linked viaparent,
deliberately handover-less (each unit's handover is authored lazily when the loop selects it). Atomic +
fail-closed (per-unit ACK validation, topic dedup incl. within the batch, full rollback on error);
epic_idadds units to an existing open epic; in-batch sibling dependencies asunit:<n>. The engine
auto-completes the epic when its last unit advances; the board shows per-epic unit progress.- Select-next-unit continuation (
_continuation_tick): after every advance the engine deterministically
selects the next open unit (priority β created_at β id; skips blocked; dependencies must be done β a
deadlock is surfaced, never a silent idle) and asks the model for exactly that unit's handover
([NEXT-UNIT]turn βstage_handoverwithtask_id); with no open units the capability-backlog leg
continues as before; with no source the loop idles ARMED (no more self-disable β only themax_tasks
cap stops it). Arming (/auto on,/autoplan on) bootstraps the loop for the FIRST unit of a freshly
planned epic (no predecessor advance exists yet), andplan_unitsunder an armed loop has the
same turn author the first handover β found live in the E2E acceptance run. /auto on [N]//auto off(automation meta-switch): one operator verb for the whole loop β full
automation (watcher + autopilot + continuation, optional task cap) vs guided mode (nothing fires by
itself; the engine recommends the selected next unit in the per-turn steering state and the operator
drives). The granular toggles remain as the advanced layer; in the recommended client/autoalso
drives the local handover poller.
Changed
- Client agent scratch is cleaned after a successful upload: the terminal client's HTTP-mediated
handover round-trip materializes per-task scratch under<codedir>/.ironclad/agent/(the handover
drop the coder reads + the feedback/capture files). These accumulated per task; after a successful
POST /feedbackthey are now removed (fail-soft). A FAILED run keeps its scratch for diagnosis and
the retry; the server-side.work/archive/history remains the durable record. - Lazily staged handovers get full parity: the
stage_handoverre-hand path (existingtask_id, no
task_json β the continuation's staging form) now applies the same id normalization, Memory brief and
lesson/ACE context injection as task creation, routes the coder deterministically off the STORED task,
and stamps the staged agent asassigned_to(canonical identity: filename == assigned_to == bodyto:). - active.md projection with handover-less units: the projection now walks newest-first to the first task
that actually HAS a handover, so a staged handover is never shadowed intoidleby a newer, not-yet-staged
unit of the decomposition. - Cost warning tells the truth: the unbounded-continuation warning now names the real cost β every
continued unit launches a PAID coder run (the local planner turn is the cheap part) β and recommends a cap
(auto on N/autoplan on N). - Deterministic, cost-aware coder routing (#1287): the coder for a handover was the orchestrator model's
pick, which defaulted to the priciest coder for everything β routine scaffolding and running a build ran on
the most expensive model even at medium effort. Coder selection is now DETERMINISTIC: each task TYPE maps to
a cost TIER (complex/standard/routine/analysis) andstage_handoverroutes to the CHEAPEST CAPABLE
coder for that tier (_route_code_agent, bycost_per_1k), reserving the top-tier coder forcomplex
(security/architecture/optimization). The operator pin still overrides. Reverses the 2026-06-25 "staged pick
is authoritative" rule.
Fixed
- Terminal client froze permanently on every confirm/guide reply: the destructive-command
warning ("re-run with --yes") and the guided-input listing returned early WITHOUT leaving the
thinking state β every subsequent keystroke was swallowed and Esc had nothing left to abort, so
the session was wedged for good. Both early-return branches now release the turn state; a
regression test drives the real component against a stub engine and types after the warning. - Single-authority completion (presence-wins) β a follow-up to the dev-loop stabilization, from a comparison
with the proven-stable predecessor gx10 loop of the: it decided completion by the
feedback FILE'S PRESENCE, never by parsing model-authored content. The advance gate now does the same β the
status:token is ADVISORY (it HOLDS a finished task only on an EXPLICITblocked/clarification_needed);
a present feedback with a done / mis-placed / absent token ADVANCES. This deletes the whole stall class
where a bare leadingstatus:(vs a frontmatter parser) or a prose-only capture defeated a content parse,
keeping the explicit-blocked guard. Principle: every engine-owned fact has ONE authoritative source. - Autonomous dev-loop stabilization β engine-owned robustness so a completed coder run reliably advances
the pipeline (fixes THE STALL surfaced during a live run, plus #1288/#1291/#1292 follow-ups). One unifying
principle: engine-owned facts (completion STATUS, routed AGENT, feedback PATH, PROJECT, CODE ROOT) are
stamped/read by the engine, never round-tripped through model-authored free text. (1) The advance gate reads
the completionstatus:tolerantly (_feedback_statusβ an in-frontmatter OR a bare leading line, via a
bounded head-scan) matching exactly what the engine's own coder prompt emits (a bare leadingstatus: done
used to be invisible to the frontmatter parser β the completed task stalled forever); a capture-mode coder's
exit-0 non-empty feedback with no status token is stampedstatus: doneat ingest. (2) A gate refusal is
now a RETRY point β the reconciler dedup keys on the feedback mtime β not a dead-end until restart. (3) The
routed agent is stamped as the single canonical identity (assigned_to+ handoverto:) so filename /
assigned_to / body / feedbackfrom:agree. (4) The advance matches the feedback by TASK ID (glob),
deriving the agent from the filename, never a caller-supplied (routing-skewed) agent. (5) The coder prompt
states the project name + code root and forbids a design-named wrapper directory (nosrc/<name>/<name>/). - Autonomous pipeline no longer stalls on a completed Claude coder run (#1288): a finished OPUS/SONNET
(claude --print) coder wrote its feedback under the handover body's own id/location (e.g. a divergent
<other-id>-feedback.mdin.work/handovers/), while the reconciler advances only on
{task_id}_{agent}-feedback.mdinfeedback_dir()β so the task stayedin_progressforever despite a
status: doneresult. The engine now states the exact feedback path (and thestatus:contract) in the
Claude coder prompt, mirroring the CODEX-o {feedback}capture, so a completed run lands where the
reconciler looks and the pipeline advances. - Design-doc paths are shown in the operator's frame (#1276):
record_design,/approveand the design-
gate status reported a vault-root-relative path (<slug>/decisions/design.md) that did not resolve from the
project root (the leadingvault/was missing). They now surface a navigable project-root-relative path
(vault/<slug>/decisions/design.md); the internal value the gate resolves against is unchanged./project newalso now seeds the single software unit under a canonicalmainslug (not the project name), so the
doc no longer double-nests as<project>/vault/<project>/β¦β it is<project>/vault/main/β¦. - Tool calls fold in the LIVE streaming preview, not only at commit (#1277): the terminal client rendered
the streaming answer as raw text (tool calls shown expanded) and only folded them into collapsed blocks when
the turn committed. The live preview now renders through the samesplitToolBlockspath as the committed
turn, so a tool call is collapsed while it streams. - The terminal client echoes a slash-command WITH its leading slash (#1278): a typed
/workwas echoed as
> workβ identical to a chat message β inviting aworkvs/workmix-up. The echo (and the persisted
transcript) now show the original input, so a command is visibly distinct from a plain message. - Code-agent handovers ship the RESOLVED bin path on
/pending(#1279):/pendingshipped the LOGICAL
bin(e.g.codex) instead of the boot-probe-resolved executable path, so the terminal client spawned a
barecodexand node's PATH could pick the wrong install (an npm shim / a Store desktop app) that rejects
exec -mβ the coder exited without producing code./pendingnow ships the resolved path the boot probe
found (the exact one/codersreports), falling back to the logicalbinonly when unresolved. - Destructive-command confirmation accepts
--yes/--confirmin any position (#1281): the confirmation
was only recognised as a TRAILING token, soproject delete X --yes --purge(a flag after--yes) re-fired
the confirm gate ("Re-run with --yes") even though the operator had already confirmed.--yes/--confirm
is now stripped as a st...
v0.0.26 β dev-loop steering rework + roster/CI/install follow-ups
Highlights
The public DEV-1 dev-loop steering rework (epic β 9 units) plus roster/CI/install follow-ups. Every shared-path mechanism is opt-in / default-off (byte-identical when unused).
Steering
- 1:1 GitHub-issue-shaped work-unit data model (labels + parent).
- No-blind-coding: a designβimplementation approval gate (
record_design+/approve). - No-blind-advance: an advance-to-
donegate that requires astatus: donefeedback signal. - An authoritative per-turn steering-state block (the engine reports its own active project/unit/stage).
launch_coderβ a first-class trigger verb for the coding handover./boardβ an LLM-free task board projected from the store.- watcher/autopilot disentangle + a task-scoped progress heartbeat + an explicit blocked state.
Roster
- Grok (xAI) as a headless code-agent + a reasoning fan-out provider.
- SONNET upgraded to Claude Sonnet 5.
Install / CI
ironcladin a new folder auto-binds to the installed runtime (no re-install); it reuses a running engine only for the same project (workdir-aware), and isolates the developed software under a code subdir.- CI runs a single Python 3.14 leg (
requires-pythonstays>=3.10).
See CHANGELOG.md [0.0.26] for the full list.
v0.0.25 β context & quality architecture (32k-window defense-in-depth)
Defense-in-depth against the 32k-window overflow on file-heavy agentic tasks β the durable L0+L1+L3 floor plus the L2 secret-env hardener. Every new behavior is default-off / byte-identical; the gated L2 read_offload is deliberately deferred.
Added
- Query-aware rolling summary (L3) (epic #1043 / #1049): on context eviction the hierarchical rolling
summary now biases retention toward the current user task β the turn is captured atrun()entry and
folded into the summarizer instruction as a bias, not a filter (recency eviction and relevance recall
via RAG are unchanged; this only steers what the summary keeps when space is tight). Fail-soft: with no
turn in scope the generic instruction is used, byte-identical to before, and the injected focus is bounded
so a large paste can't bloat the summarizer's own prompt. No new flag. First code rung of the
context-&-quality defense-in-depth epic (#1043). - In-core secret-env hardener on the CLI-runner lane (epic #1043 / #1052):
default_cli_runnerspawned
the coder subprocess (web_search,parallel_reason, and the futureread_offload) with the server's
full environment. A newengine/agent_env.pynow scrubs every secret NAME from the child env and redirects
the git/gh credential-discovery paths into an empty scratch store at that one choke-point, so a
prompt-injection in untrusted ingested content can't exfiltrate an inherited token or push via the ambient
credential β whileHOME/~/.claude(the coder's own OAuth) is preserved andCLAUDE_CONFIG_DIRis never
set (#994/#996). Fail-closed to a plain secret scrub if the redirect can't be written. Also closes the
pre-existingweb_searchenv exposure; a hard precondition for the gatedread_offload(#1053). - Emergency-rung archive + optional summarize-not-truncate (L3) (epic #1043 / #1050): the last-resort
recovery that truncates the largest turns' content to head+tail excerpts previously dropped the middle
slice silently. It now always cold-archives the discarded slice (add_bulk(source="fragment_trim"))
so B2 RAG can re-inject it query-aware next turn. An optional, default-offcontext.emergency_summarize
(GX10_EMERGENCY_SUMMARIZE) replaces the raw drop with a bounded summary, wrapped in a hard wall-clock
timeout (daemon-thread, win32-safe), skipped when a generation this turn already errored, and always
falling through to raw truncation on timeout/exception (at most one model call per invocation). The
default-off path is byte-identical to before. - Proactive ingestion accountant + shared summarize rate-limit (L3) (epic #1043 / #1051): completes the
L3 backstop. A default-offcontext.proactive_roll(GX10_PROACTIVE_ROLL) accountant runs at the
tool-result boundary and, once cumulative ingestion crossescontext.ingest_soft_frac(~0.7) of the model
window, proactively sheds the oldest whole tool rounds via a query-aware roll-summary (high floor) instead
of waiting for the reactive low-floor truncation. Acontext.max_summaries_per_turn
(GX10_MAX_SUMMARIES_PER_TURN, 0 = unlimited) shared per-turn cap now bounds the total summarizes
across ALL three triggers (steady-state roll, emergency rung, proactive) so they can't compound into
multiple full model round-trips in one turn; past the cap a roll degrades to a plain archived drop.
Per-turn counters (summaries + estimated tokens) track the cost. The default path is byte-identical. - Ranged / pattern
read_file(L1) (epic #1043 / #1047):read_filegainsstart/end(1-based
inclusive line numbers), an optional regexpattern(reads a window of lines around the first match), and
max_charsβ so the model reads only the relevant slice of a large file instead of the whole thing, and
the schema/description steer search-first (usesearch_filesto locate the lines, then read that range). A
bad range or an unmatched/invalid pattern falls back to the existing head+tail cap (never crashes). The
slice logic is mirrored in the TypeScript client (clients/inkrunTool.ts) so a local-topology read
applies the same slice, and the ink omission marker is re-steered fromfindstr/Select-Stringto
search_files(matching the server, #1046). - L0 served-window deploy passthrough (64k) (epic #1043 / #1044 / #1045):
core/scripts/spark-bootstrap.sh
gains--max-model-len/--max-num-seqsflags (previously env-only) and logs the effective window before
its idempotency check, and the private deploy driver now forwardsIRONCLAD_MAX_MODEL_LEN/
IRONCLAD_GPU_MEM_UTIL/IRONCLAD_MAX_SEQSto the remote (ssh does not forward env), so a deploy raises the
served vLLM window to 64k reproducibly without hand-editing the bootstrap default. The public core default
stays a conservative 32768 and the engine auto-adopts the served window at boot (#377). Live-verified on the
Spark: vLLM serves 65536 with the co-located Mem0 stack healthy (~43x KV headroom at 65,536 tokens/request,
~37 GB free) at gpu-mem-util 0.6 β the evidence corrects the design's 0.85, which would starve Mem0 on
the shared 121 GB unified-memory box; unsetIRONCLAD_MAX_MODEL_LENreverts to 32768 cleanly.
v0.0.24 β Operate-&-Maintain + autonomy-safety + 11 capability quick-wins
Ironclad becomes safe to run unattended: observable, recoverable, and with real autonomy-safety primitives. 22 capabilities across three areas β every new feature is default-off and byte-identical when off.
Operate & Maintain (run it unattended)
- Runtime telemetry β
GET /metrics: rolling latency / error-rate / token-cost + SLO verdict + anomaly signal. - Backup & restore for the memory tiers (Qdrant/Neo4j/Valkey) + engine state, with retention + a runbook.
- Operate scheduler β one cron entry fans out to periodic jobs (backup, prune, β¦).
- Behavioral post-deploy verify β auto-rollback to the last-good build on failure.
- Alerting pipeline β SLO/anomaly rules β outbound webhook page + inbound
POST /alertreceiver.
Autonomy-safety (safe without a human watching)
- Ambiguity auto-detector β no-guessing becomes a pre-flight gate.
- Learned-state safety β snapshot + eval-gated ACE promotion + auto-revert of a measured regression.
- Full tamper-evident audit log β who/what/when/why across the tool surface + audit-dir tamper-resistance.
- Ingestion prompt-injection defense (ADR-0012), OS exec sandbox (ADR-0013), RBAC + multi-tenant foundation (ADR-0014).
New tools & capabilities
create_issue Β· fetch_url (SSRF-guarded) Β· edit_file Β· remember Β· a feature-spec/PRD prompt Β· dependabot + a dependency-audit CI Β· log & run-artifact retention Β· /ace snapshot|rollback|unlearn.
Full detail in the CHANGELOG. Every security-sensitive feature ships an ADR with explicit remaining scope.
v0.0.23 β self-hosting hardening + always-on coder memory
v0.0.23
Self-hosting orchestrator hardening + always-on coder memory, plus deterministic release tooling and context-window robustness.
Highlights
- Coder Memory MCP is always-on β the code agents get live read-only project memory in any trust profile (no longer sealed-gated); all roster coders ship an MCP template.
- Budget-aware read cap + emergency-trim recovery β an agent can no longer overflow the model window with a single tool result:
read_filecaps to the live per-turn window budget, and the pre-flight guard truncates an irreducible oversized turn instead of failing. - Deterministic release tooling β
changelog_cut+release_prepbump the version across every file that carries it and cut the CHANGELOG in one call, so a release satisfies every version-consistency invariant. - Self-modification bootstrap machinery (epic #994) β staged-release guards (Test-PyPI-first routing, main-safe rollback), drain-before-update, an immutable protected floor, and fail-closed flip-readiness gates.
See CHANGELOG.md for the full list.