Anvil v2.2.19 is the i18n + Memory Cohesion arc. Two long-running commitments close in this release: Anvil now ships in 18 languages with a wizard picker, OS locale auto-detect, and a soft drift gate; and the seven-layer memory architecture promised since v2.2.14 is wired end-to-end with every layer GREEN. Plus a new web-based MCP Builder lands on AnvilHub, a full Claude Code parity sweep (v2.1.144 → v2.1.146) lands 15 concrete fixes including three P0 security/correctness items, and the release pipeline grows per-phase START/OK/FAIL gates that catch silent exits like the v2.2.18 Phase 6 incident.
18 Locales
The TUI, wizard, slash-command output, and remote-control viewer all flow through rust-i18n v4 in Rust and the new viewer.locales.js runtime in the browser.
Tier-1 (8 locales, 264 keys each): English, Spanish, Simplified Chinese, French, Brazilian Portuguese, Russian, Japanese, German.
Tier-2 (10 locales, 264 keys each): Korean, Italian, Turkish, Vietnamese, Polish, Indonesian, Dutch, Swedish, Norwegian Bokmål, Ukrainian.
Locale selection persists to ~/.anvil/config.json, falls back to $LANG on first launch, and applies immediately to every wizard step. The in-TUI /configure menu has a Language Picker submenu rendering all 18 locales in their native script (한국어, Русский, 中文) so users find their language without knowing the BCP-47 code.
The AnvilHub viewer ships with 176 fully-wired keys covering chrome plus all vault and config panels — vault.* (entry add/edit/delete forms, master-key modal) and config.* (SSH, Database, Plugins+MCP, Layout, Status-line editor) — routed through data-i18n-key attributes that the live re-render walker translates on locale switch with no page reload.
Seven-Layer Memory — All GREEN
The seven-layer memory architecture committed in v2.2.14 finally has all layers wired end-to-end. The 2026-05-21 cohesion audit catalogued the state, and the subsequent waves closed every RED layer.
Layer 3 (Semantic) — was RED. /memory promote <nomination-id> now actually persists nominated facts to disk. The v2.2.14 stub flipped a status flag without ever calling MemoryManager::save() — nominated facts never reached ANVIL.md. The full chain now writes the fact and appends provenance comments (# nominated_at: <ISO>, # source: nomination/<id>) before marking the nomination accepted. A new --target <file> flag routes a nomination to a specific file with relative, absolute, and ~-expanded path support.
Layer 7 (Cache) — was RED. The file-cache path-discovery bug is fixed: previously memory_budget checked a directory that no longer exists in the project-scoped layout, so cache counts always reported zero. Now uses FileCacheManager::new(cwd) to discover the actual per-project path. /memory show cache enumerates file-cache, command-cache, and QMD-cache stats. /memory prune cache --dry-run walks both FileCacheManager and CommandCacheManager for stale candidates without mutating anything.
Layer 1, 2, 4 — live introspection. /memory layer 1 renders a live snapshot of the working-memory inventory via PromptSectionsExt::iter_by_kind(). /memory show episodic unifies daily summaries, history archives, and workspace sessions. /memory prune episodic adds TTL-based retention with a trash-bin safety net so candidates move to ~/.anvil/trash/<unix-ts>/... rather than being deleted. /memory show procedural consolidates GoalManager state, on-disk skills, bundled skills, and CronManager schedule into one view.
AnvilHub /build Page + anvil-mcp-builder Micro-Service
Anvil’s /mcp builder TUI wizard from v2.2.18 now has a web counterpart. The anvil-mcp-builder micro-service runs at 127.0.0.1:4090 on the AnvilHub host and exposes three endpoints:
POST /api/builder/spec— LLM-generated MCP spec from a free-text user prompt. SSE streaming response.POST /api/builder/generate— turns the spec into a base64 tarball (Node.js, TypeScript, or Python templates).POST /api/builder/sandbox— extracts the tarball, runsanvil-sandbox-runneragainst it (network-cut), returns sandbox stdout/stderr.
Security. The operator OAuth token (for the LLM that generates specs) is loaded from the Anvil vault at startup, never from .env. The service exits 1 if vault is locked or the entry is missing; token is cached in process memory only and redacted from all log output. The sandbox endpoint runs npm install / pip install per request — a real abuse vector. Access is gated on publisher standing: user must be in the anvilhub-publishers Authentik group OR have at least one HubPackage already published.
Claude Code Parity Sweep — v2.1.144 → v2.1.146
A complete CC parity audit covered the 4-day window since v2.1.143 across 3 CC releases. 15 fixes filed and shipped this release.
P0 (3 items).
- MCP pagination (CC v2.1.144-B6 / v2.1.146-B2). Anvil’s MCP client now consumes the full
nextCursor/has_morepagination chain fortools/list,resources/list,resources/templates/list, andprompts/list. Previously MCP servers with paginated responses had everything beyond page 1 silently dropped. - Spinner/elapsed-time freeze (CC v2.1.145-B3). The TUI render queue now wakes from a wall-clock timer in addition to input events. Previously, after a terminal refocus or resize, the spinner and elapsed-time display would freeze until the next keypress.
- MCP
permissions.allownot honored (CC community #61077, security). Allow rules with patterns likemcp__server__toolormcp__server__*are now consulted at MCP tool dispatch time. Previously the allowlist was loaded fromsettings.jsonbut the MCP dispatch path bypassed it and always prompted.
P1 items include the Bash env-var permission bypass fix (security), the skill fork-context recursion guard, and resume-session model preservation. P2 sweep covers API startup timeout, mime-type magic-number fallback in Read, /branch history recovery post-EnterWorktree, MCP image fallback for unsupported MIME, skill watcher FD exhaustion prevention, theme color reset, and EnterWorktree MCP config preservation.
anvild — Separate Process Name on 7 Platforms
The background OAuth-refresh + routines daemon now runs as anvild, not anvil daemon foreground. A new anvild_path_from(anvil_binary) helper rewrites the binary path used by every supervisor unit — macOS LaunchAgent, Linux user-systemd, FreeBSD/NetBSD rc.d, Windows Task Scheduler — plus the in-TUI daemon::spawn_detached fallback. ps -ef | grep daemon now shows anvild rather than masquerading as the foreground TUI binary.
Release-Pipeline Step-Gates
scripts/release.sh now wraps every phase in step "PN: <description>" + ok "PN" / fail "PN" markers. The new scripts/release-helpers/step-gates.sh provides primitives + JSON status persistence + an EXIT-trap silent-exit detector that marks any RUNNING phase as FAIL on premature script exit.
This closes the v2.2.18 Phase 6 silent-exit class of bugs. The set +e / SSH_RC=$? / set -e pattern is applied around SSH calls so heredoc-style remote work surfaces its exit code instead of cascading into a set -e silent kill. scripts/test-release-gates.sh is the regression harness.
Test Suite
Net +50 tests across the workspace: i18n drift gate + picker invariant + 8 locale-load tests, +9 episodic / +6 promote / +6 cache / +5 working / +3 procedural for memory cohesion, +35 across all 15 CC-parity fixes, +7 publisher-standing tests in the new micro-service.
Install
Seven platforms, SHA256-verified, single binary, no runtime required.
# Homebrew (macOS & Linux)
brew install culpur/anvil/anvil
# Or download directly
curl -fsSL https://anvilhub.culpur.net/install.sh | bash
Compatibility: v2.2.19 is binary-compatible with v2.2.18 sessions. anvil --continue and anvil --resume <id> work across the upgrade. The new locale key in config.json is optional (defaults to $LANG then en). The anvild rename is supervisor-unit-level only; existing daemons keep running until next restart.
