Three days, five loomcycle releases, four arcs deeply intertwined. Arc 1: a whole-repo hardening pass (v1.9.1) closes 17 findings from a proper security review. Tenant-isolation gaps sealed on four transports (gRPC read+channel RPCs, A2A peer auth, mem9 SSRF + API-key exfil, run cancel + interrupt-resolve). Secret-exposure gaps closed at write-time. Six provider-driver fixes: Anthropic replays the thinking block on tool-use continuations; OpenAI reasoning models use max_completion_tokens; Ollama surfaces in-stream error frames; DeepSeek downgrades thinking-model fallback to deepseek-chat and drops the effort hint; grep re-checks symlink containment before os.Open; runstate delivers events under the write lock. The MCP thin client now transparently self-recovers on both HTTP and stdio (404 / -32001 re-handshake). Arc 2: CredentialDef (RFC AR) — a new substrate Def family for encrypted per-tenant secrets. Envelope AES-256-GCM with a deployment KEK (LOOMCYCLE_SECRET_KEY) and per-tenant DEK derived via HKDF-SHA256; GCM AAD binds each ciphertext to (key_id|tenant|scope|scope_id|name); fail-closed on missing KEK; current+previous KEK rotation with lazy re-encrypt. The credential_defs table (migration 0051) holds sealed ciphertext or an external-backend pointer, never plaintext; excluded from snapshots. Consumers: $cred: substitution in HTTP MCP server headers (per-request resolve; scope precedence agent>user>tenant; a shared pool posts as different users on different runs); tenant + user provider-key override by env-var name (ANTHROPIC_API_KEY at tenant scope shadows operator host key for that tenant's runs; same shape for OpenAI/Gemini/hosted Ollama/DeepSeek/Brave; fail-soft to host default). Arc 3: cost attribution (RFC AV) — a per-call token_usage ledger (migration 0052, both backends) records one row per LLM call with credential_source label (operator/tenant/user), four token buckets, priced cost. Per-call granularity is exact across mid-run provider fallback. GET /v1/_usage returns aggregated reports grouped by any combination of tenant/user/provider/model/source with a whitelisted dimension list; operator-vs-tenant split falls out of the group-by. A Web UI Usage page with group-by chips, from/to window, admin tenant focus, and a summary strip showing operator-bill vs tenant-funded split plus unpriced-calls indicator. Retention: rollup-and-prune sweeper into usage_archive; old-run archiver into runs_archive. gRPC + TypeScript + Python adapter parity in Phase 2c. Arc 4: token budgets (RFC AW). A budget is {tenant, scope, scope_id, window, soft, hard}; scope operator/tenant/user; window calendar-month UTC; most-restrictive-of-the-three-scopes wins. Enforcement: at admission, limits.Check refuses over-hard runs with runner.ErrTokenLimitExceeded (429 on HTTP, ResourceExhausted on gRPC); in flight, recordCallUsage emits an EventLimit event on newly-crossed thresholds. In-memory tracker boot-seeds from the token_usage ledger so a restart doesn't reset counters. EventLimit is a new event type carrying LimitInfo{scope, scope_id, severity, window, used, limit, message} on HTTP SSE, gRPC Run/Continue streams, MCP spawn_run result (Limits alongside Usage), the TS adapter's "limit" event type, the Python adapter's LimitInfo dataclass, and the Web UI's run terminal (amber banner soft / red hard). GET/PUT/DELETE /v1/_limits + gRPC TokenLimit(list|set|delete) share a limits.ResolveWrite confinement helper. A Web UI Limits page with a live month-to-date used column and K/M/G shorthand in the editor. Small wins: routing view (GET /v1/_routing) shows the live provider/model cascade per tier; RFC AU tenant import of Claude Code skills + MCP servers from a .claude/ directory; Path VFS synthesizes implicit-directory entries in one-level ls (fixes the missing rfcs/ folder when listing /loomcycle/). TrueNAS deploy artifacts pinned to 1.11.1.
Varela: Neuromancer-inspired self-mutating coding harness