Skip to content

Changelog

Release history for the Roboticus autonomous agent runtime. Follows conventional commits.

v1.5.1

Bug Fixes & Stability & More2026-07-10

Added: 1 change. Fixed: 7 changes. Changed: 1 change. Key changes: Mechanic disk-reclaim domain: a propose-only maintenance domain that reclaims over-retained safety/undo artifacts under the instance dir — redundant verified DB snapshots, corruption forensics, recovery snapshots, unpruned config-file backups, and orphaned model weights — each by structural signature match with a newest-N retention floor and live-file exclusion. Surfaced on the maintenance heartbeat (report-only) and applied only through an explicit operator confirm via `roboticus mechanic`, matching the workspace/plugins-skills domains. Addresses multi-GB backup accumulation that the mechanic previously never cleaned. macOS bundled-sidecar SIGKILL (v1.5.0 prod outage):the update/runtime-install path did not ad-hoc code-sign the extracted llama.cpp binaries+dylibs on macOS, so AMFI/taskgated rejected the runtime-invalid signature and SIGKILLed llama-server at exec (both the embedder :11435 and chat host :11436), silently degrading to the n-gram embedder floor and a connection-refused chat route. Install-time now ad-hoc-signs the runtime, and the daemonself-heals it once per lifetime before spawning either sidecar (unconditional re-sign, since `codesign --verify` passes on disk even while the kernel rejects the signature at exec). Mechanic hygiene routed to a paid cloud provider: the workspace grounding-judge classified ambiguous files by escalating to OpenRouter on every maintenance heartbeat (an inverted route gate) and timed out noisily. It is now pinned to the local route with `NoEscalate` (cloud impossible by construction) and runs only when that route is healthy, degrading to mechanical-only otherwise; the caller is tagged (Rule 14) so a failure is attributable without a goroutine-stack dump. The scheduler lease-renewal test is now deterministic (event-synchronized rather than wall-clock-bound), eliminating a slow-CI-runner timing flake.

Highlights

  • Mechanic disk-reclaim domain: a propose-only maintenance domain that reclaims over-retained safety/undo artifacts under the instance dir — redundant verified DB snapshots, corruption forensics, recovery snapshots, unpruned config-file backups, and orphaned model weights — each by structural signature match with a newest-N retention floor and live-file exclusion. Surfaced on the maintenance heartbeat (report-only) and applied only through an explicit operator confirm via `roboticus mechanic`, matching the workspace/plugins-skills domains. Addresses multi-GB backup accumulation that the mechanic previously never cleaned.
  • macOS bundled-sidecar SIGKILL (v1.5.0 prod outage):the update/runtime-install path did not ad-hoc code-sign the extracted llama.cpp binaries+dylibs on macOS, so AMFI/taskgated rejected the runtime-invalid signature and SIGKILLed llama-server at exec (both the embedder :11435 and chat host :11436), silently degrading to the n-gram embedder floor and a connection-refused chat route. Install-time now ad-hoc-signs the runtime, and the daemonself-heals it once per lifetime before spawning either sidecar (unconditional re-sign, since `codesign --verify` passes on disk even while the kernel rejects the signature at exec).
  • Mechanic hygiene routed to a paid cloud provider: the workspace grounding-judge classified ambiguous files by escalating to OpenRouter on every maintenance heartbeat (an inverted route gate) and timed out noisily. It is now pinned to the local route with `NoEscalate` (cloud impossible by construction) and runs only when that route is healthy, degrading to mechanical-only otherwise; the caller is tagged (Rule 14) so a failure is attributable without a goroutine-stack dump.
  • Quarantined plugin re-registered every heartbeat: the plugin registry scan walked recursively into the mechanic quarantine subtree and re-registered a dead plugin, failing (and log-spamming) on every scan. `ScanDirectory` now skips the quarantine subtree via a single shared constant so the scanner and the quarantiner agree on the path.
  • Source/dev build reported up to date instead of upgrading: version comparison ranked a non-numeric `dev-<sha>` base above a real release (lexical `d > 1`), so a source build never upgraded. A non-numeric base now sorts older than any release.
  • Maintenance heartbeat could stack overlapping passes: an over-running heartbeat re-fired back-to-back on the buffered ticker tick. The loop now drains the pending tick after each pass (single-flight), resuming at the next interval; a no-op on the happy path.
  • Disk-reclaim telemetry over-counted freed bytes on a partial-apply failure, and the apply confirm prompt hard-coded a stale per-domain reversal list. Both corrected (count reflects work actually done; the prompt is domain-agnostic).
  • README accuracy: a full line-by-line audit reconciled the banner, badges, and counts with the source of truth (channels 8, migrations 73, fuzz targets 10, bundled providers 20, test-file count), and removed an invocation of the non-existent `parity-audit` command (also excised from the developer docs).
FEATMechanic disk-reclaim domain: a propose-only maintenance domain that reclaims over-retained safety/undo artifacts under the instance dir — redundant verified DB snapshots, corruption forensics, recovery snapshots, unpruned config-file backups, and orphaned model weights — each by structural signature match with a newest-N retention floor and live-file exclusion. Surfaced on the maintenance heartbeat (report-only) and applied only through an explicit operator confirm via `roboticus mechanic`, matching the workspace/plugins-skills domains. Addresses multi-GB backup accumulation that the mechanic previously never cleaned.
FIXmacOS bundled-sidecar SIGKILL (v1.5.0 prod outage):the update/runtime-install path did not ad-hoc code-sign the extracted llama.cpp binaries+dylibs on macOS, so AMFI/taskgated rejected the runtime-invalid signature and SIGKILLed llama-server at exec (both the embedder :11435 and chat host :11436), silently degrading to the n-gram embedder floor and a connection-refused chat route. Install-time now ad-hoc-signs the runtime, and the daemonself-heals it once per lifetime before spawning either sidecar (unconditional re-sign, since `codesign --verify` passes on disk even while the kernel rejects the signature at exec).
FIXMechanic hygiene routed to a paid cloud provider: the workspace grounding-judge classified ambiguous files by escalating to OpenRouter on every maintenance heartbeat (an inverted route gate) and timed out noisily. It is now pinned to the local route with `NoEscalate` (cloud impossible by construction) and runs only when that route is healthy, degrading to mechanical-only otherwise; the caller is tagged (Rule 14) so a failure is attributable without a goroutine-stack dump.
FIXQuarantined plugin re-registered every heartbeat: the plugin registry scan walked recursively into the mechanic quarantine subtree and re-registered a dead plugin, failing (and log-spamming) on every scan. `ScanDirectory` now skips the quarantine subtree via a single shared constant so the scanner and the quarantiner agree on the path.
FIXSource/dev build reported up to date instead of upgrading: version comparison ranked a non-numeric `dev-<sha>` base above a real release (lexical `d > 1`), so a source build never upgraded. A non-numeric base now sorts older than any release.
FIXMaintenance heartbeat could stack overlapping passes: an over-running heartbeat re-fired back-to-back on the buffered ticker tick. The loop now drains the pending tick after each pass (single-flight), resuming at the next interval; a no-op on the happy path.
FIXDisk-reclaim telemetry over-counted freed bytes on a partial-apply failure, and the apply confirm prompt hard-coded a stale per-domain reversal list. Both corrected (count reflects work actually done; the prompt is domain-agnostic).
FIXREADME accuracy: a full line-by-line audit reconciled the banner, badges, and counts with the source of truth (channels 8, migrations 73, fuzz targets 10, bundled providers 20, test-file count), and removed an invocation of the non-existent `parity-audit` command (also excised from the developer docs).
CHOREThe scheduler lease-renewal test is now deterministic (event-synchronized rather than wall-clock-bound), eliminating a slow-CI-runner timing flake.

v1.5.0

Bug Fixes & Stability & More2026-07-09

Added: 3 changes. Changed: 6 changes. Fixed: 12 changes. Instrumentation: 1 change. Key changes: Hugging Bay as a selectable model-catalog source: `roboticus models catalog {search,files,install}` and the dashboard Catalog controls can now discover and install GGUF chat models from [Hugging Bay](https://huggingbay.xyz) as well as HuggingFace, selected with `--source huggingbay` (CLI) or the `source` control param (dashboard). A new `internal/catalog.Source` interface fronts both registries; `GGUFSpec` gains an optional `url` so a source that hosts files by a self-contained URL (rather than a repo/revision/file triple) can be installed and re-provisioned on restart. The SHA-256 pin remains the single trust boundary: downloaded bytes are fail-closed verified against the resolved hash regardless of origin, so an alternative source's hosted bytes are untrusted and the content hash is the control (identical guarantee to the HuggingFace path). Recall index-health coverage gauge: `RunHygiene` records, after the reactivation FTS rebuild, the active-memory total and how many active rows are still missing their FTS row (`HygieneReport.ActiveMemoryTotal` / `ActiveMemoryMissingFTSAfter`, via a `db.MemoryIndexHealth` probe). Post-repair the deficit should be `0`; a non-zero value is the red flag that recall did not fully heal, surfaced in the mechanic hygiene report. Best-effort — a probe error never fails the hygiene run. Semantic subgoal typing replaces the pronoun-scramble denylist (CC-2): derived subgoals are typed via the embedding intent classifier, and only genuine task subgoals flow into executive-state population and the verifier coverage contract; conversational (identity/chat/ack/roleplay) fragments are excluded. This retires the brittle, language-specific `dropConversationalIdentityGoals` phrase denylist — no phrase or word matching. The shared classifier exemplars are untouched. Background and off-pipeline callers are pinned to the local maintenance route (CC-4): the distillation heartbeat, `turn_analysis`, and the session-less `sessions_analyze` diagnostic now request `Service.MaintenanceModel()` with `AgentRole=subagent` instead of re-deciding the route per call. The LLM reranker resolves an empty model to `Models.Primary` at both assembly seams (mirroring the already-safe workspace judge). Under the current local-only prod config this is structural regression-proofing; it keeps these callers local even if a cloud fallback is later added. The onboarding interview is intentionally left un-pinned pending an operator product call.

Highlights

  • Hugging Bay as a selectable model-catalog source: `roboticus models catalog {search,files,install}` and the dashboard Catalog controls can now discover and install GGUF chat models from [Hugging Bay](https://huggingbay.xyz) as well as HuggingFace, selected with `--source huggingbay` (CLI) or the `source` control param (dashboard). A new `internal/catalog.Source` interface fronts both registries; `GGUFSpec` gains an optional `url` so a source that hosts files by a self-contained URL (rather than a repo/revision/file triple) can be installed and re-provisioned on restart. The SHA-256 pin remains the single trust boundary: downloaded bytes are fail-closed verified against the resolved hash regardless of origin, so an alternative source's hosted bytes are untrusted and the content hash is the control (identical guarantee to the HuggingFace path).
  • Recall index-health coverage gauge: `RunHygiene` records, after the reactivation FTS rebuild, the active-memory total and how many active rows are still missing their FTS row (`HygieneReport.ActiveMemoryTotal` / `ActiveMemoryMissingFTSAfter`, via a `db.MemoryIndexHealth` probe). Post-repair the deficit should be `0`; a non-zero value is the red flag that recall did not fully heal, surfaced in the mechanic hygiene report. Best-effort — a probe error never fails the hygiene run.
  • Config-driven embedding backfill batch: the embedding backfill's hardcoded `LIMIT 25` becomes `memory.embedding_backfill_batch` (`0` = built-in default 25), so a large dark corpus can be healed faster or a slow local embedder eased, without a binary change.
  • Semantic subgoal typing replaces the pronoun-scramble denylist (CC-2): derived subgoals are typed via the embedding intent classifier, and only genuine task subgoals flow into executive-state population and the verifier coverage contract; conversational (identity/chat/ack/roleplay) fragments are excluded. This retires the brittle, language-specific `dropConversationalIdentityGoals` phrase denylist — no phrase or word matching. The shared classifier exemplars are untouched.
  • Background and off-pipeline callers are pinned to the local maintenance route (CC-4): the distillation heartbeat, `turn_analysis`, and the session-less `sessions_analyze` diagnostic now request `Service.MaintenanceModel()` with `AgentRole=subagent` instead of re-deciding the route per call. The LLM reranker resolves an empty model to `Models.Primary` at both assembly seams (mirroring the already-safe workspace judge). Under the current local-only prod config this is structural regression-proofing; it keeps these callers local even if a cloud fallback is later added. The onboarding interview is intentionally left un-pinned pending an operator product call.
  • Render-2 reflect/continuation overlay is compacted: the trailing reflect/continuation overlay no longer restates TASK, AUTHORITATIVE OBSERVED RESULTS, and KEY TOOL OUTCOMES, because the full conversation history is already sent above the overlay; `TOTOF.RenderOverlay` / `ContinuationArtifact.RenderOverlay` emit only open issues plus the finalization/continuation instruction, cutting a re-prefill worth roughly 37% of local prefill on those inferences.
  • Go toolchain bumped to 1.26.5 (the `go` directive in `go.mod`, which CI reads), patching the reachable `crypto/tls` stdlib vulnerability GO-2026-5856.
  • `golang.org/x/crypto` bumped 0.49.0 → 0.52.0 (dependabot security update).
FEATHugging Bay as a selectable model-catalog source: `roboticus models catalog {search,files,install}` and the dashboard Catalog controls can now discover and install GGUF chat models from [Hugging Bay](https://huggingbay.xyz) as well as HuggingFace, selected with `--source huggingbay` (CLI) or the `source` control param (dashboard). A new `internal/catalog.Source` interface fronts both registries; `GGUFSpec` gains an optional `url` so a source that hosts files by a self-contained URL (rather than a repo/revision/file triple) can be installed and re-provisioned on restart. The SHA-256 pin remains the single trust boundary: downloaded bytes are fail-closed verified against the resolved hash regardless of origin, so an alternative source's hosted bytes are untrusted and the content hash is the control (identical guarantee to the HuggingFace path).
FEATRecall index-health coverage gauge: `RunHygiene` records, after the reactivation FTS rebuild, the active-memory total and how many active rows are still missing their FTS row (`HygieneReport.ActiveMemoryTotal` / `ActiveMemoryMissingFTSAfter`, via a `db.MemoryIndexHealth` probe). Post-repair the deficit should be `0`; a non-zero value is the red flag that recall did not fully heal, surfaced in the mechanic hygiene report. Best-effort — a probe error never fails the hygiene run.
FEATConfig-driven embedding backfill batch: the embedding backfill's hardcoded `LIMIT 25` becomes `memory.embedding_backfill_batch` (`0` = built-in default 25), so a large dark corpus can be healed faster or a slow local embedder eased, without a binary change.
CHORESemantic subgoal typing replaces the pronoun-scramble denylist (CC-2): derived subgoals are typed via the embedding intent classifier, and only genuine task subgoals flow into executive-state population and the verifier coverage contract; conversational (identity/chat/ack/roleplay) fragments are excluded. This retires the brittle, language-specific `dropConversationalIdentityGoals` phrase denylist — no phrase or word matching. The shared classifier exemplars are untouched.
CHOREBackground and off-pipeline callers are pinned to the local maintenance route (CC-4): the distillation heartbeat, `turn_analysis`, and the session-less `sessions_analyze` diagnostic now request `Service.MaintenanceModel()` with `AgentRole=subagent` instead of re-deciding the route per call. The LLM reranker resolves an empty model to `Models.Primary` at both assembly seams (mirroring the already-safe workspace judge). Under the current local-only prod config this is structural regression-proofing; it keeps these callers local even if a cloud fallback is later added. The onboarding interview is intentionally left un-pinned pending an operator product call.
CHORERender-2 reflect/continuation overlay is compacted: the trailing reflect/continuation overlay no longer restates TASK, AUTHORITATIVE OBSERVED RESULTS, and KEY TOOL OUTCOMES, because the full conversation history is already sent above the overlay; `TOTOF.RenderOverlay` / `ContinuationArtifact.RenderOverlay` emit only open issues plus the finalization/continuation instruction, cutting a re-prefill worth roughly 37% of local prefill on those inferences.
CHOREGo toolchain bumped to 1.26.5 (the `go` directive in `go.mod`, which CI reads), patching the reachable `crypto/tls` stdlib vulnerability GO-2026-5856.
CHORE`golang.org/x/crypto` bumped 0.49.0 → 0.52.0 (dependabot security update).
CHOREThe onboarding interview may use the best available model (R2 decision): resolving the product call noted above, the first-run interview is allowed to route to the strongest model rather than the pinned local maintenance route, so onboarding quality is not floor-bound.
FIXCircuit breaker is no longer net-harmful on a sole-local route (CC-1): a breaker exists to fail over, so a sole-local route (`fallbacks=[]`) with nowhere to fail over must not block the only model once its breaker opens — that converted a transient or slow local into a total outage. `breakerSkipError` now bypasses an ordinary open state for a sole-local route, a successful bypassed serve heals the stale trip, and credit-exhaustion (402) plus operator force-open still block. `fallback_count` no longer reports a phantom `fallbacks=1` on a sole-candidate turn (it is gated on a real remaining candidate).
FIXA turn that answered is no longer stamped `degraded` (CC-1, F-A3): the toolless-stall override fired on `RequestTools>0 && ToolCallCount==0` plus a liveness warning, with no check that the turn actually failed to answer, so a slow local model answering directly from recall or world-knowledge was mislabeled `degraded` and poisoned the quality tracker. The silent-failure signal now also requires that no non-empty answer was finalized; the true stall (offered tools, ran none, empty answer, stalled) still degrades.
FIXLeaked scaffold is stripped by provenance (CC-2): a weak model echoing the injected memory/executive scaffold (`[Memory Index]` / `[Active Memory]` / `[Working State]` / TOTOF) as its answer is now caught by matching the answer against the actual scaffold strings injected this turn, not by re-recognizing a rendered prefix — so a reshaped or repositioned echo no longer leaks. A majority-scaffold answer becomes a non-answer recovery; a stray leaked line is stripped with authored prose preserved. The echoable empty-index fallback string is dropped so the model cannot parrot it.
FIXReactivated memory is rebuilt into recall — heals 75% dark memory (CC-3):decay-hygiene deletes a memory's `memory_fts` rows on inactivation, but the reactivation paths healed only base `memory_state`, so reactivated memories stayed dark to recall and rendered false "no memory" denials (measured on prod: 584/779, 75%, of active semantic memories were missing from `memory_fts`). A `repairReactivatedMemoryDerivedRows` pass — the exact inverse of the inactivation delete, idempotent and byte-identical to trigger-built rows — runs each hygiene cycle, andmigration 085 one-time-heals the existing dark backlog.
FIXA gutted index no longer produces a confident false denial (CC-3): `AssembleContext` reclassifies a `no_evidence` gap as `MemoryGapIndexDegraded` when the active corpus has dark FTS rows, rendering a non-denying, `recall_memory`-pointing notice instead of asserting absence; the verifier treats that state as not-proof-of-absence, so a non-derivable prompt must hedge while a recall-free prompt (arithmetic/time) stays unconstrained. The wasted working/ambient pre-render is reordered to a fallback that runs only when retrieval did not populate context (one assembly per turn instead of two).
FIXWorld-knowledge subgoals skip the wasted verifier repair (CC-2 latency): a covered factual subgoal fired `unsupported_subgoal` and triggered a second full-prefill verifier repair, because the evidence-optional gate never covered world-knowledge facts. A task subgoal the embedding classifier confidently places in `IntentQuestion` is marked `WorldKnowledge` and treated as evidence-optional, but only after every existing evidence-requiring guard still runs (entity-support, freshness, policy, action-plan, tool/artifact proofs), so it is non-regressing by construction.
FIXPronoun scramble at the executive-state seam: identity questions were being recorded as the agent's own verified subgoals, scrambling operator-vs-agent pronouns; they are filtered at the `BuildVerificationContext` convergence point across both the decomposition/task-synthesis path and the user-prompt fallback (superseded by the CC-2 semantic typing above, landed first as the foundation fix).
FIXFlaky `-race internal/db` writer-gate FAIL: the writer-gate completion backstops were tight wall-clock bounds (200ms–1s) on ops that finish in under 1ms, so a correct gate tripped them under pathological runner slowness. They now route through one deadlock-scale constant (`gateDeadlockGuard = 30s`) — only a true hang trips it; the tight fairness/ordering assertions that slowness cannot break are kept.
FIXEvidence-recovery augments the model's answer instead of replacing it (issue #173): the post-success verifier retry was discarding a correct model answer and substituting recovered evidence; it now augments, never replaces, so a right answer survives the recovery path. Evidence projection also skips all memory-introspection (not only the empty-recall case), keeping the projected evidence clean.
FIXVerifier subgoal-coverage excludes non-content directives (issue #172): framework/scaffold directive fragments were counted as uncovered subgoals, firing spurious coverage failures; they are filtered before the coverage contract is evaluated.
FIXCLI / mechanic output honors the house formatting rules: user-facing output had em dashes (against the no-em-dash rule) and the mechanic proposal/status block did not wrap or column-align; the block now wraps within its column, aligns the status column, and uses text-presentation warn/gear glyphs so Windows Terminal does not eat the trailing space. An AST guard test fails the build on any em dash in a user-facing string literal.
FIXCI fuzz + config-watcher flakes eliminated at root: the Soak + Extended Fuzz job routed through the deterministic `ci-fuzz.sh` guard so the Go fuzzing coordinator's benign "context deadline exceeded" shutdown race under runner contention no longer fails the build (real crashers still fail), and `ConfigWatcher` detects changes by content hash instead of mtime so two writes sharing a coarse mtime tick (a Windows flake, and a latent same-tick-edit correctness bug) are no longer missed.
CHORESession-less router selections are now audited (Rule 14): `recordModelSelectionFromRequest` previously early-returned when turn/session were absent, so every background selection was unrecorded (prod: 209 events, 0 with a background turn id). It now substitutes unique sentinels (`turn_id = "bg-"+db.NewID()`, `session = "background"`, a `-background` strategy suffix) so a context-free router decision is auditable and background events are not collapsed into one row by the upsert. Recall index-health (`db.MemoryIndexHealth`) surfaces active-vs-indexed coverage in the hygiene report.

v1.4.4

Foundation-RCA Remediation2026-07-09

Added: 2 changes. Changed: 4 changes. Fixed: 7 changes. Everything since v1.4.3 traces to one root-cause pass (`docs/releases/foundation-rca.md`) that collapsed a spread of fidelity, recall, and local-primary symptoms into four common causes, each fixed at its root. CC-1 (control/diagnostic plane stops speaking cloud): the circuit breaker no longer blocks the only model on a sole-local route (`fallbacks=[]`), and a turn that answered directly from recall is no longer stamped `degraded` by the toolless-stall override. CC-2 (typed scaffold, not echoable text): derived subgoals are typed via the embedding classifier (retiring a brittle pronoun-scramble denylist), leaked scaffold is stripped by provenance instead of by rendered prefix, and world-knowledge subgoals skip a wasted verifier repair. CC-3 (an active memory is recallable again): decay had left 584/779 (75%) of active semantic memories dark to recall; reactivation now rebuilds the derived FTS index and migration 085 heals the backlog, so a gutted index renders a hedged notice instead of a confident false 'no memory' denial. CC-4 (background paths stop drifting to cloud): background callers (distillation, turn analysis, reranker) are pinned to the local maintenance route and every session-less router selection is now audited. Also: a Go 1.26.5 bump patching crypto/tls GO-2026-5856, and a ~37% local-prefill win from a compacted reflect/continuation overlay. Gated by `go test -race`, an ABORT premortem, and a full 10/10-green behavioral soak.

Highlights

  • Sole-local circuit breaker fixed (CC-1), on a local-only setup with no cloud fallback, an open breaker used to block the only model and turn a slow local into a total outage. It now bypasses an ordinary open state for a sole-local route (credit-exhaustion and operator force-open still block), and a successful serve heals the stale trip.
  • A correct answer is no longer marked `degraded` (CC-1), a slow local model answering directly from memory offers tools, calls none, and trips a liveness timer; that coincidence used to stamp the turn `degraded` and poison the quality tracker. The signal now also requires that no answer was produced.
  • Typed subgoals retire the pronoun-scramble denylist (CC-2), identity questions were being recorded as the agent's own verified subgoals and scrambling operator-vs-agent pronouns. Subgoals are now typed by the embedding classifier so only genuine task subgoals count. No phrase matching.
  • Leaked scaffold stripped by provenance (CC-2), a weak model echoing the injected memory/executive scaffold as its answer is now caught by matching against the actual injected strings, so a reshaped or repositioned echo no longer leaks.
  • 75% dark memory healed (CC-3), decay-hygiene deleted a memory's search-index rows on inactivation but reactivation healed only the base row, so 584/779 active memories were unsearchable and produced false 'no memory' denials. Reactivation now rebuilds the search index each hygiene cycle and migration 085 heals the existing backlog; a gutted index renders a hedged notice instead of a confident denial.
  • Background callers pinned local (CC-4), distillation, turn analysis, and the reranker no longer re-decide the route per call and drift to cloud (the recorded 47,541 background cloud calls); every session-less router selection is now audited.
  • Go 1.26.5 security bump, patches the reachable crypto/tls vulnerability GO-2026-5856.
  • ~37% local-prefill win, the reflect/continuation overlay no longer restates sections already present in the conversation history above it.
FEATRecall index-health coverage gauge (CC-3), `RunHygiene` records, after the reactivation FTS rebuild, the active-memory total and how many active rows are still missing their FTS row (`HygieneReport.ActiveMemoryTotal`/`ActiveMemoryMissingFTSAfter` via `db.MemoryIndexHealth`); post-repair the deficit should be 0, and a non-zero value is the red flag that recall did not fully heal.
FEATConfig-driven embedding backfill batch (CC-3), the embedding backfill's hardcoded `LIMIT 25` becomes `memory.embedding_backfill_batch` (0 = built-in default 25), so a large dark corpus heals faster or a slow local embedder is eased, without a binary change.
CHORESemantic subgoal typing (CC-2), derived subgoals are typed via the embedding intent classifier; only genuine task subgoals flow into executive-state and the verifier coverage contract, retiring the brittle language-specific `dropConversationalIdentityGoals` denylist. No phrase or word matching; the shared classifier exemplars are untouched.
CHOREBackground callers pinned to the local maintenance route (CC-4), distillation, `turn_analysis`, and the session-less `sessions_analyze` diagnostic request `Service.MaintenanceModel()` with `AgentRole=subagent`; the LLM reranker resolves an empty model to `Models.Primary` at both assembly seams (the workspace judge was verified already safe). Interview is intentionally left un-pinned pending an operator product call.
CHORERender-2 reflect/continuation overlay compacted, the trailing overlay no longer restates TASK, AUTHORITATIVE OBSERVED RESULTS, and KEY TOOL OUTCOMES, because the full conversation history is already sent above it; `RenderOverlay` emits only open issues plus the finalization/continuation instruction, cutting a re-prefill worth roughly 37% of local prefill. Isolated for independent revert.
CHOREGo toolchain bumped to 1.26.5, patches the reachable `crypto/tls` stdlib vulnerability GO-2026-5856 (govulncheck: 0 vulnerabilities on 1.26.5, was 1 on 1.26.4).
FIXSole-local circuit breaker (CC-1), a sole-local route (`fallbacks=[]`) with nowhere to fail over no longer blocks the only model once its breaker opens; `breakerSkipError` bypasses an ordinary open state and a successful bypassed serve heals the stale trip, while credit-exhaustion (402) and operator force-open still block. `fallback_count` no longer reports a phantom `fallbacks=1` on a sole-candidate turn.
FIXA turn that answered is no longer stamped `degraded` (CC-1, F-A3), the toolless-stall override fired on offered-tools + no-tool-call + a liveness warning without checking whether the turn actually failed to answer, mislabeling a correct direct answer as degraded. It now also requires that no non-empty answer was finalized; the true stall (empty answer) still degrades.
FIXLeaked scaffold stripped by provenance (CC-2), a weak model echoing the injected memory/executive scaffold (`[Memory Index]`/`[Active Memory]`/`[Working State]`/TOTOF) as its answer is caught by matching against the actual scaffold strings injected this turn, not by re-recognizing a rendered prefix, so a reshaped or repositioned echo no longer leaks; the echoable empty-index fallback string is dropped.
FIXReactivated memory rebuilt into recall, heals 75% dark memory (CC-3), decay-hygiene deletes a memory's `memory_fts` rows on inactivation but reactivation healed only base `memory_state`, so reactivated memories stayed dark to recall (measured: 584/779, 75%, of active semantic memories missing from `memory_fts`). `repairReactivatedMemoryDerivedRows` runs each hygiene cycle (idempotent, byte-identical to trigger-built rows) and migration 085 one-time-heals the existing backlog.
FIXA gutted index no longer produces a confident false denial (CC-3), `AssembleContext` reclassifies a no-evidence gap as `MemoryGapIndexDegraded` when the active corpus has dark FTS rows, rendering a non-denying `recall_memory`-pointing notice; the verifier treats it as not-proof-of-absence so a non-derivable prompt must hedge while arithmetic/time prompts stay unconstrained. The wasted pre-render is reordered to a single assembly per turn.
FIXWorld-knowledge subgoals skip the wasted verifier repair (CC-2 latency), a covered factual subgoal fired `unsupported_subgoal` and triggered a second full-prefill verifier repair; a task subgoal the classifier confidently places in `IntentQuestion` is now evidence-optional, but only after every existing evidence-requiring guard still runs, so it is non-regressing by construction.
FIXFlaky `-race internal/db` writer-gate FAIL eliminated deterministically, the writer-gate completion backstops were tight wall-clock bounds (200ms-1s) on ops that finish in under 1ms, so a correct gate tripped them under a starved runner; they now route through one deadlock-scale constant (`gateDeadlockGuard = 30s`), while the tight fairness/ordering assertions that slowness cannot break are kept.

v1.4.3

New Features & More2026-07-08

Added: 2 changes. Fixed: 2 changes. Instrumentation: 1 change. Key changes: LittleLamb default-on deterministic tool-caller: when the bundled chat host is enabled, a no-native-tool-call turn now asks the sidecar's grammar-constrained decision whether to force a valid on-surface tool call or keep the model's direct answer, so local tool-calling no longer depends on each model emitting well-formed calls. Augment-not-replace: a correct drafted answer is preserved alongside any forced call, and every routing decision (router input, choice, and fail-open error) is recorded in turn diagnostics for RCA. Speed-aware local model auto-pick: setup and install choose the local chat model by measured backend throughput, not RAM alone. A discrete NVIDIA/AMD GPU gets the larger tier; an Apple/integrated (Metal/Vulkan) or CPU backend is capped to a model it can actually run at interactive speed, so a machine is never handed a model that fits memory but crawls. Adds Qwen2.5-3B as an eval candidate (the measured sweet spot for integrated GPUs). Local-primary latency: dynamic grounding (local time, proof obligations) is emitted after conversation history, so the static prefix and the growing history reuse the llama.cpp KV cache across a turn's ReAct inferences and across turns; only the volatile tail re-prefills. The bundled chat endpoint is exempted from the 60s fast-endpoint timeout so a legitimately long local inference is not cut off mid-generation. A no-progress route now advances to a fallback route before terminating instead of churning in place. Durable memory reactivation: a one-time heal re-activates durable memory that decay wrongly pruned (follow-through on the v1.4.2 recall fix), touching only decay-pruned entries and never those superseded, deduplicated, or derivable.

Highlights

  • LittleLamb default-on deterministic tool-caller: when the bundled chat host is enabled, a no-native-tool-call turn now asks the sidecar's grammar-constrained decision whether to force a valid on-surface tool call or keep the model's direct answer, so local tool-calling no longer depends on each model emitting well-formed calls. Augment-not-replace: a correct drafted answer is preserved alongside any forced call, and every routing decision (router input, choice, and fail-open error) is recorded in turn diagnostics for RCA.
  • Speed-aware local model auto-pick: setup and install choose the local chat model by measured backend throughput, not RAM alone. A discrete NVIDIA/AMD GPU gets the larger tier; an Apple/integrated (Metal/Vulkan) or CPU backend is capped to a model it can actually run at interactive speed, so a machine is never handed a model that fits memory but crawls. Adds Qwen2.5-3B as an eval candidate (the measured sweet spot for integrated GPUs).
  • Local-primary latency: dynamic grounding (local time, proof obligations) is emitted after conversation history, so the static prefix and the growing history reuse the llama.cpp KV cache across a turn's ReAct inferences and across turns; only the volatile tail re-prefills. The bundled chat endpoint is exempted from the 60s fast-endpoint timeout so a legitimately long local inference is not cut off mid-generation. A no-progress route now advances to a fallback route before terminating instead of churning in place.
  • Durable memory reactivation: a one-time heal re-activates durable memory that decay wrongly pruned (follow-through on the v1.4.2 recall fix), touching only decay-pruned entries and never those superseded, deduplicated, or derivable.
  • Per-attempt local KV-cache reuse, per-turn inference timing (migration 084), toolless-stall silent-failure detection, and full LittleLamb routing telemetry recorded in turn diagnostics (Rule 14).
FEATLittleLamb default-on deterministic tool-caller: when the bundled chat host is enabled, a no-native-tool-call turn now asks the sidecar's grammar-constrained decision whether to force a valid on-surface tool call or keep the model's direct answer, so local tool-calling no longer depends on each model emitting well-formed calls. Augment-not-replace: a correct drafted answer is preserved alongside any forced call, and every routing decision (router input, choice, and fail-open error) is recorded in turn diagnostics for RCA.
FEATSpeed-aware local model auto-pick: setup and install choose the local chat model by measured backend throughput, not RAM alone. A discrete NVIDIA/AMD GPU gets the larger tier; an Apple/integrated (Metal/Vulkan) or CPU backend is capped to a model it can actually run at interactive speed, so a machine is never handed a model that fits memory but crawls. Adds Qwen2.5-3B as an eval candidate (the measured sweet spot for integrated GPUs).
FIXLocal-primary latency: dynamic grounding (local time, proof obligations) is emitted after conversation history, so the static prefix and the growing history reuse the llama.cpp KV cache across a turn's ReAct inferences and across turns; only the volatile tail re-prefills. The bundled chat endpoint is exempted from the 60s fast-endpoint timeout so a legitimately long local inference is not cut off mid-generation. A no-progress route now advances to a fallback route before terminating instead of churning in place.
FIXDurable memory reactivation: a one-time heal re-activates durable memory that decay wrongly pruned (follow-through on the v1.4.2 recall fix), touching only decay-pruned entries and never those superseded, deduplicated, or derivable.
CHOREPer-attempt local KV-cache reuse, per-turn inference timing (migration 084), toolless-stall silent-failure detection, and full LittleLamb routing telemetry recorded in turn diagnostics (Rule 14).

v1.4.2

Bug Fixes & Stability2026-07-07

Fixed: 4 changes. Key changes: Recall no longer ignores durable memory: recall was excluding consolidated ("promoted") memory — roughly four-fifths of stored content on a long-lived instance — and decaying the rest on a blind timer, so an agent progressively lost reach of its own history. Durable memory is now a first-class recall candidate (promoted-fallback leg) and recall reinforces confidence, so usefulness keeps memory alive rather than a timer aging it out. Plus six consolidation correctness fixes: silent semantic-fact loss during promotion, a dead index-sync branch that never demoted stale entries, distinct load-bearing-token preservation through dedup, UTF-8-safe content previews, and fail-loud episodic dedup. Context-compaction digest now runs: the proof-carrying digest Engine was configured on yet producing zero digests, because the producer built from a different message base than the consumer read, so every digest was discarded. Producer and consumer now build from one shared persisted base, and the splice is anchored to a content fingerprint of the coverage boundary so a shifted window can never drop a live turn. Load-bearing tokens (numbers, paths) are preserved.

Highlights

  • Recall no longer ignores durable memory: recall was excluding consolidated ("promoted") memory — roughly four-fifths of stored content on a long-lived instance — and decaying the rest on a blind timer, so an agent progressively lost reach of its own history. Durable memory is now a first-class recall candidate (promoted-fallback leg) and recall reinforces confidence, so usefulness keeps memory alive rather than a timer aging it out. Plus six consolidation correctness fixes: silent semantic-fact loss during promotion, a dead index-sync branch that never demoted stale entries, distinct load-bearing-token preservation through dedup, UTF-8-safe content previews, and fail-loud episodic dedup.
  • Context-compaction digest now runs: the proof-carrying digest Engine was configured on yet producing zero digests, because the producer built from a different message base than the consumer read, so every digest was discarded. Producer and consumer now build from one shared persisted base, and the splice is anchored to a content fingerprint of the coverage boundary so a shifted window can never drop a live turn. Load-bearing tokens (numbers, paths) are preserved.
  • Tool-hydration stall: an agent loading tools on demand could stall by describing the load instead of calling the freshly hydrated tools; the loop no longer treats hydration as a terminal step, and the reactive guard that papered over it is removed.
  • Windows install hardening: `install.ps1` upgrades in place over an on-PATH binary (with a shadowing warning), quiesces a running daemon before replacing its binary, and retries runtime extraction under file-in-use. A single source-of-truth managed-binary path keeps self-update, the service, and the installer agreed on the authoritative binary.
FIXRecall no longer ignores durable memory: recall was excluding consolidated ("promoted") memory — roughly four-fifths of stored content on a long-lived instance — and decaying the rest on a blind timer, so an agent progressively lost reach of its own history. Durable memory is now a first-class recall candidate (promoted-fallback leg) and recall reinforces confidence, so usefulness keeps memory alive rather than a timer aging it out. Plus six consolidation correctness fixes: silent semantic-fact loss during promotion, a dead index-sync branch that never demoted stale entries, distinct load-bearing-token preservation through dedup, UTF-8-safe content previews, and fail-loud episodic dedup.
FIXContext-compaction digest now runs: the proof-carrying digest Engine was configured on yet producing zero digests, because the producer built from a different message base than the consumer read, so every digest was discarded. Producer and consumer now build from one shared persisted base, and the splice is anchored to a content fingerprint of the coverage boundary so a shifted window can never drop a live turn. Load-bearing tokens (numbers, paths) are preserved.
FIXTool-hydration stall: an agent loading tools on demand could stall by describing the load instead of calling the freshly hydrated tools; the loop no longer treats hydration as a terminal step, and the reactive guard that papered over it is removed.
FIXWindows install hardening: `install.ps1` upgrades in place over an on-PATH binary (with a shadowing warning), quiesces a running daemon before replacing its binary, and retries runtime extraction under file-in-use. A single source-of-truth managed-binary path keeps self-update, the service, and the installer agreed on the authoritative binary.

v1.4.1

Bug Fixes & Stability & More2026-07-06

Added: 2 changes. Changed: 3 changes. Fixed: 7 changes. Key changes: `models recommend` unified advisor: one command across three horizons — default ranks recorded benchmark evidence, `--scan` probes configured providers and applies a chain (was `models suggest`), `--discover` ranks installable HuggingFace models for this host's RAM (was `models whichllm`). Tool-caller (LittleLamb) sidecar status surfaced in Models → Local Runtime. Breaking — `mechanic` is now exactly two subcommands: `check` (read-only diagnostics across all maintenance domains) and `repair` (apply, with confirmation). The per-domain subcommands (`config-repair`, `autonomic`, `workspace`, `plugins-skills`, `security`) and the `fix` alias are removed; their logic runs inside `check`/`repair`. Breaking — `models` selection is one advisor: `models suggest` and `models whichllm` are removed, folded into `models recommend` (see Added).

Highlights

  • `models recommend` unified advisor: one command across three horizons — default ranks recorded benchmark evidence, `--scan` probes configured providers and applies a chain (was `models suggest`), `--discover` ranks installable HuggingFace models for this host's RAM (was `models whichllm`).
  • Tool-caller (LittleLamb) sidecar status surfaced in Models → Local Runtime.
  • Breaking — `mechanic` is now exactly two subcommands: `check` (read-only diagnostics across all maintenance domains) and `repair` (apply, with confirmation). The per-domain subcommands (`config-repair`, `autonomic`, `workspace`, `plugins-skills`, `security`) and the `fix` alias are removed; their logic runs inside `check`/`repair`.
  • Breaking — `models` selection is one advisor: `models suggest` and `models whichllm` are removed, folded into `models recommend` (see Added).
  • Product-knowledge pack refreshed to `1.4.0.2` (recommend advisor, mechanic check/repair, RBAC onboarding, knowledge-graph memory), deliverable via `roboticus pack update` without a binary upgrade.
  • Answer fidelity — the verifier no longer degrades a correct answer. A verbatim "repeat back the values I gave you" request was scored by subgoal coverage against the request's label words ("access code", "region", "spend limit"), which a correct value-answer legitimately omits — so it false-failed 0/2, force-retried, and the re-roll could drop a digit (`9300`→`930`). Coverage now skips verbatim-reproduction requests (their fidelity is enforced by content preservation, not label matching), and a verifier retry that resolves none of the original concerns while shortening the answer no longer replaces the original.
  • Circuit breaker: operator reset now clears the durable credit-trip, so a topped-up 402 provider no longer comes back OPEN on the next restart.
  • Catalog RAM footprints are no longer ~3x inflated (backend-authoritative estimator; a ~23 GB quant no longer advertises "needs ~67 GB"); multimodal projector (mmproj/CLIP) GGUFs are excluded from the chat catalog.
FEAT`models recommend` unified advisor: one command across three horizons — default ranks recorded benchmark evidence, `--scan` probes configured providers and applies a chain (was `models suggest`), `--discover` ranks installable HuggingFace models for this host's RAM (was `models whichllm`).
FEATTool-caller (LittleLamb) sidecar status surfaced in Models → Local Runtime.
CHOREBreaking — `mechanic` is now exactly two subcommands: `check` (read-only diagnostics across all maintenance domains) and `repair` (apply, with confirmation). The per-domain subcommands (`config-repair`, `autonomic`, `workspace`, `plugins-skills`, `security`) and the `fix` alias are removed; their logic runs inside `check`/`repair`.
CHOREBreaking — `models` selection is one advisor: `models suggest` and `models whichllm` are removed, folded into `models recommend` (see Added).
CHOREProduct-knowledge pack refreshed to `1.4.0.2` (recommend advisor, mechanic check/repair, RBAC onboarding, knowledge-graph memory), deliverable via `roboticus pack update` without a binary upgrade.
FIXAnswer fidelity — the verifier no longer degrades a correct answer. A verbatim "repeat back the values I gave you" request was scored by subgoal coverage against the request's label words ("access code", "region", "spend limit"), which a correct value-answer legitimately omits — so it false-failed 0/2, force-retried, and the re-roll could drop a digit (`9300`→`930`). Coverage now skips verbatim-reproduction requests (their fidelity is enforced by content preservation, not label matching), and a verifier retry that resolves none of the original concerns while shortening the answer no longer replaces the original.
FIXCircuit breaker: operator reset now clears the durable credit-trip, so a topped-up 402 provider no longer comes back OPEN on the next restart.
FIXCatalog RAM footprints are no longer ~3x inflated (backend-authoritative estimator; a ~23 GB quant no longer advertises "needs ~67 GB"); multimodal projector (mmproj/CLIP) GGUFs are excluded from the chat catalog.
FIX`models exercise` rows render atomically (concurrent local + cloud lanes no longer cross-wire); model-comparison latency is formatted adaptively (min/sec/ms); the bundled chat host is probed instead of mislabeled `provider_unconfigured`.
FIXEmbedding "Behavioral Correction" card no longer false-alarms when the bundled embedder is serving at semantic strength; the genuine unconfigured case shows calmer, plainer copy.
FIXHallucinated email tool names (e.g. `proton_bridge`) redirect to the real `read_inbox`.
FIXSkill usage is credited on activation and retirement uses a 90-day floor, so the mechanic no longer false-flags actively-used skills as stale.

v1.4.0

New Features & More2026-07-04

Added: 6 changes. Changed: 1 change. Fixed: 1 change. Security: 2 changes. Key changes: RBAC: per-role tool policy, in-chat `/grant` with presets + `@username`, F18 in-chat group onboarding (`/admit`) with `user admitted-chats` / `user revoke-chat` CLI, dashboard Access tab. Agent self-service: `set_config` (operator-authorized config mutation), read-only `mcp_status`, dashboard "Connect (OAuth)" turnkey MCP authorization, `provider balance`. Empty memory recall returns a neutral, non-reflectable signal and memory previews are rune-safe, so weak local models no longer parrot recall scaffolding as the answer. Windows upgrade (#164): the embedder runtime re-provisions in place by quiescing the bundled sidecars first (freeing the locked DLL), then resuming them — no manual daemon stop.

Highlights

  • RBAC: per-role tool policy, in-chat `/grant` with presets + `@username`, F18 in-chat group onboarding (`/admit`) with `user admitted-chats` / `user revoke-chat` CLI, dashboard Access tab.
  • Agent self-service: `set_config` (operator-authorized config mutation), read-only `mcp_status`, dashboard "Connect (OAuth)" turnkey MCP authorization, `provider balance`.
  • Autonomic mechanic: memory-pressure / tool-bloat / model-fit domains that conclude→recommend→act (operator-confirmed), with per-tick overrun instrumentation.
  • Model selection: footprint-fit selection, whichllm bridge, jargon-free onboarding, download cancel/queue, measured throughput in the model exercise.
  • Knowledge graph: clustering (incremental + cluster-aware retrieval + dashboard view), entity linking, HippoRAG PPR prototype, agent-owned Obsidian vault projection.
  • Runtime: a-la-carte GPU backend provisioning for the bundled chat host, local-route stop sequences, latency-aware context budget on slow local routes.
  • Empty memory recall returns a neutral, non-reflectable signal and memory previews are rune-safe, so weak local models no longer parrot recall scaffolding as the answer.
  • Windows upgrade (#164): the embedder runtime re-provisions in place by quiescing the bundled sidecars first (freeing the locked DLL), then resuming them — no manual daemon stop.
FEATRBAC: per-role tool policy, in-chat `/grant` with presets + `@username`, F18 in-chat group onboarding (`/admit`) with `user admitted-chats` / `user revoke-chat` CLI, dashboard Access tab.
FEATAgent self-service: `set_config` (operator-authorized config mutation), read-only `mcp_status`, dashboard "Connect (OAuth)" turnkey MCP authorization, `provider balance`.
FEATAutonomic mechanic: memory-pressure / tool-bloat / model-fit domains that conclude→recommend→act (operator-confirmed), with per-tick overrun instrumentation.
FEATModel selection: footprint-fit selection, whichllm bridge, jargon-free onboarding, download cancel/queue, measured throughput in the model exercise.
FEATKnowledge graph: clustering (incremental + cluster-aware retrieval + dashboard view), entity linking, HippoRAG PPR prototype, agent-owned Obsidian vault projection.
FEATRuntime: a-la-carte GPU backend provisioning for the bundled chat host, local-route stop sequences, latency-aware context budget on slow local routes.
CHOREEmpty memory recall returns a neutral, non-reflectable signal and memory previews are rune-safe, so weak local models no longer parrot recall scaffolding as the answer.
FIXWindows upgrade (#164): the embedder runtime re-provisions in place by quiescing the bundled sidecars first (freeing the locked DLL), then resuming them — no manual daemon stop.
FIX`set_config` refuses the fund-config class (`wallet`/`treasury`/`yield`/`revenue`/`self_funding`), closing an agent-reachable fund-redirection / spend-cap-removal path found by the ABORT premortem.
FIXConfig writes are serialized through a single channel-actor so concurrent daemon writers cannot lose updates; the dashboard OAuth flow is bound to the daemon lifecycle and no longer data-races the config path.

v1.3.11

Bug Fixes & Stability & More2026-07-03

Fixed: 2 changes. Documentation: 1 change. Known: 1 change. Key changes: `roboticus upgrade all` no longer aborts on a locked embedder DLL (Windows).Windows cannot overwrite a file held open by another process, so re-provisioning the bundled embedder runtime while the daemon is running failed to extract `libomp140.x86_64.dll`. That transient lock was misclassified as a broken artifact and returned as afatalerror — aborting the whole upgrade even though the main binary had already updated. It is now treated as atransient, retryable condition: a non-fatal warning with a "stop Roboticus and re-run" hint, so the binary upgrade completes and embeddings run on the n-gram fallback until re-provisioned. (The fail-loud classification for a genuinely corrupt asset or a bad extractor is unchanged.) The over-classification dated to the v1.3.3 "fail loud on broken runtime provisioning" change, which did not account for a Windows in-use lock. `roboticus daemon stop` works on Windows. It previously failed with `signal SIGTERM to pid …: not supported by windows` — Go's `os.Process.Signal` does not support `SIGTERM`/`SIGKILL` on Windows, so stop errored before doing anything. The stop signal is now delivered through a platform-specific path: `TerminateProcess` on Windows, POSIX signals unchanged on Unix/macOS. Folded the v1.3.10 turnkey MCP OAuth feature (`mcp auth`) into the evergreen reference docs — the wiki MCP section and the `[[mcp.servers]]` field table (incl. the `oauth` / `oauth_client_id` / `oauth_token_url` fields) in `configuration.md`. On Windows the daemon's embedder/chat sidecars are not yet grouped in a Job Object, so a forceful `daemon stop` can orphan the embedder `llama-server` and keep its DLL locked. Full embedder re-provisioning on Windows needs that Job Object (tracked); the above fixes un-brick the upgrade and restore `daemon stop`.

Highlights

  • `roboticus upgrade all` no longer aborts on a locked embedder DLL (Windows).Windows cannot overwrite a file held open by another process, so re-provisioning the bundled embedder runtime while the daemon is running failed to extract `libomp140.x86_64.dll`. That transient lock was misclassified as a broken artifact and returned as afatalerror — aborting the whole upgrade even though the main binary had already updated. It is now treated as atransient, retryable condition: a non-fatal warning with a "stop Roboticus and re-run" hint, so the binary upgrade completes and embeddings run on the n-gram fallback until re-provisioned. (The fail-loud classification for a genuinely corrupt asset or a bad extractor is unchanged.) The over-classification dated to the v1.3.3 "fail loud on broken runtime provisioning" change, which did not account for a Windows in-use lock.
  • `roboticus daemon stop` works on Windows. It previously failed with `signal SIGTERM to pid …: not supported by windows` — Go's `os.Process.Signal` does not support `SIGTERM`/`SIGKILL` on Windows, so stop errored before doing anything. The stop signal is now delivered through a platform-specific path: `TerminateProcess` on Windows, POSIX signals unchanged on Unix/macOS.
  • Folded the v1.3.10 turnkey MCP OAuth feature (`mcp auth`) into the evergreen reference docs — the wiki MCP section and the `[[mcp.servers]]` field table (incl. the `oauth` / `oauth_client_id` / `oauth_token_url` fields) in `configuration.md`.
  • On Windows the daemon's embedder/chat sidecars are not yet grouped in a Job Object, so a forceful `daemon stop` can orphan the embedder `llama-server` and keep its DLL locked. Full embedder re-provisioning on Windows needs that Job Object (tracked); the above fixes un-brick the upgrade and restore `daemon stop`.
FIX`roboticus upgrade all` no longer aborts on a locked embedder DLL (Windows).Windows cannot overwrite a file held open by another process, so re-provisioning the bundled embedder runtime while the daemon is running failed to extract `libomp140.x86_64.dll`. That transient lock was misclassified as a broken artifact and returned as afatalerror — aborting the whole upgrade even though the main binary had already updated. It is now treated as atransient, retryable condition: a non-fatal warning with a "stop Roboticus and re-run" hint, so the binary upgrade completes and embeddings run on the n-gram fallback until re-provisioned. (The fail-loud classification for a genuinely corrupt asset or a bad extractor is unchanged.) The over-classification dated to the v1.3.3 "fail loud on broken runtime provisioning" change, which did not account for a Windows in-use lock.
FIX`roboticus daemon stop` works on Windows. It previously failed with `signal SIGTERM to pid …: not supported by windows` — Go's `os.Process.Signal` does not support `SIGTERM`/`SIGKILL` on Windows, so stop errored before doing anything. The stop signal is now delivered through a platform-specific path: `TerminateProcess` on Windows, POSIX signals unchanged on Unix/macOS.
CHOREFolded the v1.3.10 turnkey MCP OAuth feature (`mcp auth`) into the evergreen reference docs — the wiki MCP section and the `[[mcp.servers]]` field table (incl. the `oauth` / `oauth_client_id` / `oauth_token_url` fields) in `configuration.md`.
CHOREOn Windows the daemon's embedder/chat sidecars are not yet grouped in a Job Object, so a forceful `daemon stop` can orphan the embedder `llama-server` and keep its DLL locked. Full embedder re-provisioning on Windows needs that Job Object (tracked); the above fixes un-brick the upgrade and restore `daemon stop`.

v1.3.10

New Features & More2026-07-03

Added: 2 changes. Changed: 3 changes. Fixed: 4 changes. Documentation: 1 change. Key changes: Turnkey MCP OAuth — `roboticus mcp auth <NAME>`. Authorize an OAuth-protected MCP server with no token to paste: the CLI runs the full discovery chain (RFC 9728 protected-resource metadata → RFC 8414 authorization-server metadata → RFC 7591 dynamic client registration), opens the authorize page, completes the PKCE code exchange on a loopback redirect, and stores the token in the machine keystore. The daemon resolves and refreshes that token on startup, so a configured OAuth server connects on the next restart. Static `auth_token_env` bearer servers keep working unchanged. `roboticus daemon restart` reports both the old and the new PID, so a restart is verifiable at a glance instead of leaving you to guess whether the process actually rolled. The embedding-provider dropdown always offers "bundled-llama.cpp (recommended)" as a first-class option, folding the legacy `llama-cpp` / `bundled-embedder` spellings into it — the local-first embedder is always one click away, no manual provider string required. Dashboard dropdowns are themed to match the rest of the console (a styled custom control layered over the native `<select>` via progressive enhancement, so it stays keyboard- and screen-reader-accessible and degrades to the native control if scripting is off).

Highlights

  • Turnkey MCP OAuth — `roboticus mcp auth <NAME>`. Authorize an OAuth-protected MCP server with no token to paste: the CLI runs the full discovery chain (RFC 9728 protected-resource metadata → RFC 8414 authorization-server metadata → RFC 7591 dynamic client registration), opens the authorize page, completes the PKCE code exchange on a loopback redirect, and stores the token in the machine keystore. The daemon resolves and refreshes that token on startup, so a configured OAuth server connects on the next restart. Static `auth_token_env` bearer servers keep working unchanged.
  • `roboticus daemon restart` reports both the old and the new PID, so a restart is verifiable at a glance instead of leaving you to guess whether the process actually rolled.
  • The embedding-provider dropdown always offers "bundled-llama.cpp (recommended)" as a first-class option, folding the legacy `llama-cpp` / `bundled-embedder` spellings into it — the local-first embedder is always one click away, no manual provider string required.
  • Dashboard dropdowns are themed to match the rest of the console (a styled custom control layered over the native `<select>` via progressive enhancement, so it stays keyboard- and screen-reader-accessible and degrades to the native control if scripting is off).
  • The "bundled-local" placeholder is gone from routing and config. The bundled chat host reports and routes by the real model name/file (e.g. `bundled-llama.cpp/Qwen2.5-7B-Instruct-Q4_K_M.gguf`) everywhere — CLI, `/status`, diagnostics, and setup — so what you configured is what you see.
  • Thinking-model reasoning never leaks into the answer. Unclosed `<think>` and dangling `</think>` fragments (emitted by reasoning GGUFs that get cut off) are stripped alongside closed reasoning blocks, so a local thinking model's scratch work stays out of the user-visible reply.
  • Weak local models can no longer be blocked from a tool they named. A direct call to a real, registered catalog tool auto-hydrates that tool onto the session surface and proceeds (authority still enforced), instead of bouncing the model into a request-tools two-step it often fumbles on a small box.
  • The constrained router judges the drafted reply, not the bare request. The LittleLamb backstop now sees the model's own draft answer and only forces a tool call when that draft genuinely fails the request — it no longer over-forces tools on turns the model already answered well.
FEATTurnkey MCP OAuth — `roboticus mcp auth <NAME>`. Authorize an OAuth-protected MCP server with no token to paste: the CLI runs the full discovery chain (RFC 9728 protected-resource metadata → RFC 8414 authorization-server metadata → RFC 7591 dynamic client registration), opens the authorize page, completes the PKCE code exchange on a loopback redirect, and stores the token in the machine keystore. The daemon resolves and refreshes that token on startup, so a configured OAuth server connects on the next restart. Static `auth_token_env` bearer servers keep working unchanged.
FEAT`roboticus daemon restart` reports both the old and the new PID, so a restart is verifiable at a glance instead of leaving you to guess whether the process actually rolled.
CHOREThe embedding-provider dropdown always offers "bundled-llama.cpp (recommended)" as a first-class option, folding the legacy `llama-cpp` / `bundled-embedder` spellings into it — the local-first embedder is always one click away, no manual provider string required.
CHOREDashboard dropdowns are themed to match the rest of the console (a styled custom control layered over the native `<select>` via progressive enhancement, so it stays keyboard- and screen-reader-accessible and degrades to the native control if scripting is off).
CHOREThe "bundled-local" placeholder is gone from routing and config. The bundled chat host reports and routes by the real model name/file (e.g. `bundled-llama.cpp/Qwen2.5-7B-Instruct-Q4_K_M.gguf`) everywhere — CLI, `/status`, diagnostics, and setup — so what you configured is what you see.
FIXThinking-model reasoning never leaks into the answer. Unclosed `<think>` and dangling `</think>` fragments (emitted by reasoning GGUFs that get cut off) are stripped alongside closed reasoning blocks, so a local thinking model's scratch work stays out of the user-visible reply.
FIXWeak local models can no longer be blocked from a tool they named. A direct call to a real, registered catalog tool auto-hydrates that tool onto the session surface and proceeds (authority still enforced), instead of bouncing the model into a request-tools two-step it often fumbles on a small box.
FIXThe constrained router judges the drafted reply, not the bare request. The LittleLamb backstop now sees the model's own draft answer and only forces a tool call when that draft genuinely fails the request — it no longer over-forces tools on turns the model already answered well.
FIXAnswer-fidelity guards catch weak-model context-dump echoes, so framework scaffolding (topic anchors, evidence refs, tool-operations headers) a small model parrots back never reaches the user.
CHOREFull documentation sweep: removed superseded/orphaned artifacts, corrected the README guard chain and stale counts, fixed false fields and defaults in `configuration.md`, reconciled `memory-architecture-spec.md`'s FTS-trigger contradictions (including a false `marshalOpenAI()` reference), refreshed wiki staleness (bundled embedder vs. "Ollama by default", v1.3.0 framing), rewrote the orphaned health-check doc to the real `health` / `mechanic` surfaces, and fixed all dead links.

v1.3.9

Bug Fixes & Stability & More2026-07-03

Added: 4 changes. Changed: 5 changes. Fixed: 10 changes. Security: 3 changes. Key changes: Broad GPU offload (CUDA / ROCm / SYCL), pulled a la carte. No GPU binary is bundled any longer; the package ships only the CPU/Metal binary and stays light. On boot the chat host detects the host GPU vendor and, in the background, fetches ONLY the matching vendor-native llama.cpp backend for that silicon (NVIDIA CUDA, AMD ROCm/HIP, Intel SYCL), else the cross-vendor Vulkan binary, SHA256-verified fail-closed, then hot-restarts onto it (the sidecar serves on CPU/Metal until it lands, so boot is never blocked and an offline box just stays on CPU). A vendor-native binary that fails at runtime downgrades to Vulkan before CPU, and `/status` reports the real offload backend in use (`cuda-gpu` / `rocm-gpu` / `sycl-gpu` / `vulkan-gpu` / `metal` / `cpu`). `get_tool_list` — active discovery of the full tool catalog by keyword, so the model finds and loads a tool before ever claiming a capability is unavailable. Local responsiveness: the prompt now reuses the llama.cpp KV prefix cache. The bundled chat host was re-prefilling the entire framework prompt every turn. The stable system prefix is HMAC-wrapped independently and byte-stable across turns, the per-session boundary key persists (instead of regenerating each turn), and the per-turn dynamic tail (local time, proof obligations, capability snapshot) is a separate post-catalog message so it can never perturb the cached prefix. Cross-turn prompt-eval collapses by roughly 20-30x on the measured hardware. Lean base tool surface. Every turn ships a minimal base tool set in a fixed order for prefix-cache stability; the model pulls more on demand via `request_tools` / `get_tool_list`. Installs carrying a stale `tool_search.top_k=15` are migrated to the lean default on repair.

Highlights

  • Broad GPU offload (CUDA / ROCm / SYCL), pulled a la carte. No GPU binary is bundled any longer; the package ships only the CPU/Metal binary and stays light. On boot the chat host detects the host GPU vendor and, in the background, fetches ONLY the matching vendor-native llama.cpp backend for that silicon (NVIDIA CUDA, AMD ROCm/HIP, Intel SYCL), else the cross-vendor Vulkan binary, SHA256-verified fail-closed, then hot-restarts onto it (the sidecar serves on CPU/Metal until it lands, so boot is never blocked and an offline box just stays on CPU). A vendor-native binary that fails at runtime downgrades to Vulkan before CPU, and `/status` reports the real offload backend in use (`cuda-gpu` / `rocm-gpu` / `sycl-gpu` / `vulkan-gpu` / `metal` / `cpu`).
  • `get_tool_list` — active discovery of the full tool catalog by keyword, so the model finds and loads a tool before ever claiming a capability is unavailable.
  • `fetch_asset` — download remote binary media.
  • `roboticus models catalog` and `models catalog install` — search the model catalog and its files from the CLI, and download + SHA-verify + pin a catalog GGUF, at parity with the dashboard Catalog tab.
  • Local responsiveness: the prompt now reuses the llama.cpp KV prefix cache. The bundled chat host was re-prefilling the entire framework prompt every turn. The stable system prefix is HMAC-wrapped independently and byte-stable across turns, the per-session boundary key persists (instead of regenerating each turn), and the per-turn dynamic tail (local time, proof obligations, capability snapshot) is a separate post-catalog message so it can never perturb the cached prefix. Cross-turn prompt-eval collapses by roughly 20-30x on the measured hardware.
  • Lean base tool surface. Every turn ships a minimal base tool set in a fixed order for prefix-cache stability; the model pulls more on demand via `request_tools` / `get_tool_list`. Installs carrying a stale `tool_search.top_k=15` are migrated to the lean default on repair.
  • Thinking-model lifecycle is first-class. A reasoning-emitting local model is probed as alive (not mistaken for a dead host), its reasoning is bounded by a config-driven `--reasoning-budget`, an answerless `finish_reason=length` is handled as a budget overrun (not no-progress churn), and completion `max_tokens` is sized to the real answer headroom.
  • Group chat speaks only when addressed, recognizing `@handle` mentions via the platform `getMe` identity rather than display-name substring matching.
FEATBroad GPU offload (CUDA / ROCm / SYCL), pulled a la carte. No GPU binary is bundled any longer; the package ships only the CPU/Metal binary and stays light. On boot the chat host detects the host GPU vendor and, in the background, fetches ONLY the matching vendor-native llama.cpp backend for that silicon (NVIDIA CUDA, AMD ROCm/HIP, Intel SYCL), else the cross-vendor Vulkan binary, SHA256-verified fail-closed, then hot-restarts onto it (the sidecar serves on CPU/Metal until it lands, so boot is never blocked and an offline box just stays on CPU). A vendor-native binary that fails at runtime downgrades to Vulkan before CPU, and `/status` reports the real offload backend in use (`cuda-gpu` / `rocm-gpu` / `sycl-gpu` / `vulkan-gpu` / `metal` / `cpu`).
FEAT`get_tool_list` — active discovery of the full tool catalog by keyword, so the model finds and loads a tool before ever claiming a capability is unavailable.
FEAT`fetch_asset` — download remote binary media.
FEAT`roboticus models catalog` and `models catalog install` — search the model catalog and its files from the CLI, and download + SHA-verify + pin a catalog GGUF, at parity with the dashboard Catalog tab.
CHORELocal responsiveness: the prompt now reuses the llama.cpp KV prefix cache. The bundled chat host was re-prefilling the entire framework prompt every turn. The stable system prefix is HMAC-wrapped independently and byte-stable across turns, the per-session boundary key persists (instead of regenerating each turn), and the per-turn dynamic tail (local time, proof obligations, capability snapshot) is a separate post-catalog message so it can never perturb the cached prefix. Cross-turn prompt-eval collapses by roughly 20-30x on the measured hardware.
CHORELean base tool surface. Every turn ships a minimal base tool set in a fixed order for prefix-cache stability; the model pulls more on demand via `request_tools` / `get_tool_list`. Installs carrying a stale `tool_search.top_k=15` are migrated to the lean default on repair.
CHOREThinking-model lifecycle is first-class. A reasoning-emitting local model is probed as alive (not mistaken for a dead host), its reasoning is bounded by a config-driven `--reasoning-budget`, an answerless `finish_reason=length` is handled as a budget overrun (not no-progress churn), and completion `max_tokens` is sized to the real answer headroom.
CHOREGroup chat speaks only when addressed, recognizing `@handle` mentions via the platform `getMe` identity rather than display-name substring matching.
CHORE`/status` tells the truth, cleanly. Each section renders as a heading with bulleted facts, the executing model shows a clean name (not the raw GGUF path), and the bundled host reports the REAL model, not a `bundled-local` placeholder.
FIXThe everyday-assistant recall loop. `/clear` now actually resets context (it archives the session so the next turn starts fresh); greetings, bare acknowledgements, and bot self-status are no longer stored as durable recallable memory; working-memory recall is deduped; and a config-driven `--repeat-penalty` curbs token-level repetition. Together these break the self-reinforcing greeting/status loop on a small local model.
FIXVerifier over-fired on trivial turns. A simple arithmetic answer is now recognized as derivable and no longer forced through a grounding-evidence retry.
FIX`read_inbox` honored the wrong window. The requested days window is enforced client-side.
FIXThe mail poller was silently non-functional. Every poll cycle is instrumented (searched / delivered / skipped) and allowlist-dropped senders are surfaced above DEBUG.
FIXStale bundled-chat routing pin is migrated to the current provider on upgrade.
FIXWeather cron bound the wrong location. Unbound location placeholders bind to the configured home location at cron execution.
FIXMaintenance intervals are completion-gated (last-run stamped after work, not before), and background memory curation defers while a user turn is in flight.
FIXBundled-route context budget is sized to the sidecar's real context window (fixing two context-overflow bugs), with the resolved window surfaced in `/status`.
FIXGPU serve-probe waits for generation-readiness (retry until the model can actually generate, not a one-shot probe at first `/health`) and scales its window with GGUF size, so a slow-loading large model is no longer stranded on CPU.
FIXTelegram formatting: `- ` / `* ` list markers render as bullets.
FIXweb_search SSRF parity. web_search refuses a redirect that escalates onto a private, reserved, or cloud-metadata address (reusing `http_fetch`'s egress policy), while still trusting the operator-configured endpoint (including a local search gateway).
FIXFail-closed SHA256 verify on every fetched llama.cpp binary (CPU, Vulkan, and the vendor-native GPU backends), the binary-side parallel of the GGUF gate.
FIXAnswer-fidelity shaping. The model no longer narrates internal tool-plumbing (`request_tools` / `get_tool_list` / the catalog), names tools it does not have, or confabulates framework rationale in the user-facing answer; a `request_tools` plumbing string is never shipped as the final answer.

v1.3.8

Bug Fixes & Stability & More2026-06-30

Added: 4 changes. Changed: 1 change. Fixed: 13 changes. Folded: 4 changes. Security: 4 changes. Key changes: In-chat operator onboarding. An operator can `/grant <role> <sender>` in a channel to bind a new sender to an RBAC role — hard operator-gated, no self-claim. Proactive slow-path notice. A slow-but-not-failed turn now tells the user it's still working (cold-start aware) and, near the deadline, offers to raise the limit — instead of a silent wait that ends in a give-up. Mechanic owns host tuning. llama.cpp ctx-size is RAM-derived (clamped) and flash-attn is enabled only where the backend supports it (Metal), both reported by the mechanic. Removed models no longer reappear. The models-config write now does a full `[models]`-table rewrite instead of an `ApplyConfigPatch` JSON-merge, so map-key deletions (policy/overrides/timeouts) persist instead of being resurrected.

Highlights

  • In-chat operator onboarding. An operator can `/grant <role> <sender>` in a channel to bind a new sender to an RBAC role — hard operator-gated, no self-claim.
  • Proactive slow-path notice. A slow-but-not-failed turn now tells the user it's still working (cold-start aware) and, near the deadline, offers to raise the limit — instead of a silent wait that ends in a give-up.
  • `roboticus models gc` — pin-safe reclaim of orphaned model weights (never deletes the active embedder or chat-host GGUF; dry-run by default).
  • Scoped CLI runner — a skill can run allowlisted CLI binaries without a full bash grant, executed directly (no shell, so metacharacters are inert), operator/self-gen-gated, sandboxed. (Security-ratified; see Security below.)
  • Mechanic owns host tuning. llama.cpp ctx-size is RAM-derived (clamped) and flash-attn is enabled only where the backend supports it (Metal), both reported by the mechanic.
  • Removed models no longer reappear. The models-config write now does a full `[models]`-table rewrite instead of an `ApplyConfigPatch` JSON-merge, so map-key deletions (policy/overrides/timeouts) persist instead of being resurrected.
  • Scorecard alias double-counting. Scorecard rows collapse provider/`:latest` aliases (`ollama/phi4-mini:latest` == `ollama/phi4-mini`) into one row.
  • Benchmark tool-choice fidelity. Jamba-class models that accept `tool_choice=required` but answer in prose are downgraded to `auto` (and a prose reply is no longer misclassified as "ignored required"); self-contained C0 prompts no longer arm a forced tool call they cannot honor.
FEATIn-chat operator onboarding. An operator can `/grant <role> <sender>` in a channel to bind a new sender to an RBAC role — hard operator-gated, no self-claim.
FEATProactive slow-path notice. A slow-but-not-failed turn now tells the user it's still working (cold-start aware) and, near the deadline, offers to raise the limit — instead of a silent wait that ends in a give-up.
FEAT`roboticus models gc` — pin-safe reclaim of orphaned model weights (never deletes the active embedder or chat-host GGUF; dry-run by default).
FEATScoped CLI runner — a skill can run allowlisted CLI binaries without a full bash grant, executed directly (no shell, so metacharacters are inert), operator/self-gen-gated, sandboxed. (Security-ratified; see Security below.)
CHOREMechanic owns host tuning. llama.cpp ctx-size is RAM-derived (clamped) and flash-attn is enabled only where the backend supports it (Metal), both reported by the mechanic.
FIXRemoved models no longer reappear. The models-config write now does a full `[models]`-table rewrite instead of an `ApplyConfigPatch` JSON-merge, so map-key deletions (policy/overrides/timeouts) persist instead of being resurrected.
FIXScorecard alias double-counting. Scorecard rows collapse provider/`:latest` aliases (`ollama/phi4-mini:latest` == `ollama/phi4-mini`) into one row.
FIXBenchmark tool-choice fidelity. Jamba-class models that accept `tool_choice=required` but answer in prose are downgraded to `auto` (and a prose reply is no longer misclassified as "ignored required"); self-contained C0 prompts no longer arm a forced tool call they cannot honor.
FIXScorecard scores models, not the framework. Framework-authored guard-exhaustion content (typed-evidence recovery / honest blocker) is tagged `response_rejected` and excluded from the exercise scorecard.
FIXDegraded embeddings no longer poison recall. When a configured embedding provider silently drops to the n-gram floor at runtime, the daemon rebinds to the validated bundled sidecar (debounced, fail-closed) instead of serving floor-grade vectors.
FIXMemory no longer ingests its own degradation. Wrong-identity ("developed by Microsoft…") and degenerate low-quality turns are refused at the memory-ingest gate, so they can't be recalled and compound.
FIXExplicit cancellation is honored. "Cancel that" / "never mind" / "do X instead" now neutralizes a pending action even when it stays on-topic, instead of the stale action surviving.
FIXBenchmark daemon-down honesty. `models exercise` of the bundled host with the daemon down now fails with an actionable message instead of a raw connection error.
FIXBundled chat host starts on Metal again (release blocker). The bundled llama.cpp server changed `--flash-attn` to a valued argument; roboticus was emitting a bare flag, so the bundled chat host failed to launch on macOS (the flagship no-Ollama path). It now passes `--flash-attn on`/`off` explicitly.
FIXHonest answers are no longer withheld. When the grounding judge forgives a response as honest grounded content, that forgiveness is now terminal across the verifier retry too — a forgiven answer is delivered instead of being re-run to exhaustion and replaced with a canned "we held this back" non-answer.
FIXA typo in `config set` no longer bricks the install. The raw config-write path now validates (and recovers from a decoder panic) before writing, and all config writes are atomic (temp + rename). `models remove` fully purges a model that is both primary and a fallback.
FIXTelegram rendering. Model filenames with intraword underscores (`…-Q4_K_M`) render literally instead of being mangled into italics, and `/status` uses clean section headers instead of terminal box-drawing rails.
FIXClearer failure messages for context overflow (names the local-host `ctx_size`/RAM remedy) and provider outages (topology-accurate, no false "fell back to a limited model"); `/api/mcp/connect` returns 400/502 for client/upstream errors instead of a blanket 500.
CHORE`roboticus models remove <model>` (alias `delete`) — drop a model from the primary/fallback routing chain and clear its per-model settings (policy, role-eligibility, overrides, timeouts, blocked/canary references). Promotes the first fallback when the primary is removed; alias-aware so `ollama/x:latest` matches the configured `ollama/x`.
CHORE`models list --include-inactive` — by default the comparison table now shows only active models (in routing, provider configured); `--include-inactive` reveals scorecard history with a `ROUTE` column and guidance (routed models → `models remove`; history-only rows → `models reset`).
CHORETerse skill index. `list-available-skills` returns a lean id + brief index (full detail on demand via `{"skill":"<id>"}`) so verbose skills no longer blow the agent prompt budget.
CHOREIntrospection-completeness shaping. Self-assessment / "what can you do" turns are shaped to cover their full surface (capabilities, tools, memory, limits), grounded in verifiable facts — placed so it never perturbs the KV-cache prefix.
FIXOnboarding authority moved to the daemon. The in-chat `/grant` flow now parses in the connector and decides authority + writes RBAC in the daemon, resolving the operator's actual configured authority (a config/TOML operator is no longer silently refused), rejecting operator self-grant, and writing the role atomically.
FIXScoped CLI runner ratified. Cleared by an independent security review and an adversarial pass (no-shell direct exec, bare-name allowlist enforced on both sides, fail-closed when unconfigured, gated as a dangerous capability) — its threat surface is a strict subset of the existing bash tool.
FIXThe tool-policy gate fails closed. With no policy engine wired, a dangerous tool is denied rather than allowed.
FIXSubprocess execution hardened — output is bounded at write time and the process group is killed on timeout.

v1.3.7

Bug Fixes & Stability & More2026-06-27

Added: 5 changes. Changed: 4 changes. Fixed: 20 changes. Key changes: Operator circuit kill-switch. `roboticus circuit open|quarantine <provider>` lets the operator force a provider out of rotation (and back) without editing config, for fast incident response. DB-access fairness foundations. A write-fairness gate with per-subsystem, caller-tagged write accounting and a daemon-routed reset, plus writer lock-hold instrumentation at the choke point. Every hygiene cycle now surfaces who spent the single serialized writer's budget (Rule 14), the groundwork for the priority-admission gate. All-in on shaping: guard exhaustion never substitutes a canned message. When a guard chain exhausts, the model's own content is delivered through a single answer-fidelity delivery chokepoint; the now-dead canned-message helpers were removed. A correct answer is never discarded for a templated non-answer (F25). Capability-denial over-constrainer culled to observe-only. The reactive capability-denial guard is de-fanged to honesty-only (it suppresses no policy/sandbox/financial/prompt-leak guard) and logs every would-fire for the termination soak.

Highlights

  • Operator circuit kill-switch. `roboticus circuit open|quarantine <provider>` lets the operator force a provider out of rotation (and back) without editing config, for fast incident response.
  • DB-access fairness foundations. A write-fairness gate with per-subsystem, caller-tagged write accounting and a daemon-routed reset, plus writer lock-hold instrumentation at the choke point. Every hygiene cycle now surfaces who spent the single serialized writer's budget (Rule 14), the groundwork for the priority-admission gate.
  • SIGUSR1 goroutine dump for hang diagnostics — the daemon writes a full goroutine trace to `~/.roboticus/goroutine-dump-<ts>.txt` on signal, the tool that root-caused the boot-hang and startup-stall incidents this cycle (#6).
  • Background inference-storm attribution. Caller-id instrumentation tags every background inference so a runaway driver can be pinned from recorded state rather than guessed (Rule 14).
  • Autonomy is not permission. The Agents page now states plainly that raising autonomy does not grant new authority (F22).
  • All-in on shaping: guard exhaustion never substitutes a canned message. When a guard chain exhausts, the model's own content is delivered through a single answer-fidelity delivery chokepoint; the now-dead canned-message helpers were removed. A correct answer is never discarded for a templated non-answer (F25).
  • Capability-denial over-constrainer culled to observe-only. The reactive capability-denial guard is de-fanged to honesty-only (it suppresses no policy/sandbox/financial/prompt-leak guard) and logs every would-fire for the termination soak.
  • Zero cloud budget degrades, it does not block. An autonomous turn with no cloud budget falls back to the free local route instead of hard-failing (educate, don't forbid).
FEATOperator circuit kill-switch. `roboticus circuit open|quarantine <provider>` lets the operator force a provider out of rotation (and back) without editing config, for fast incident response.
FEATDB-access fairness foundations. A write-fairness gate with per-subsystem, caller-tagged write accounting and a daemon-routed reset, plus writer lock-hold instrumentation at the choke point. Every hygiene cycle now surfaces who spent the single serialized writer's budget (Rule 14), the groundwork for the priority-admission gate.
FEATSIGUSR1 goroutine dump for hang diagnostics — the daemon writes a full goroutine trace to `~/.roboticus/goroutine-dump-<ts>.txt` on signal, the tool that root-caused the boot-hang and startup-stall incidents this cycle (#6).
FEATBackground inference-storm attribution. Caller-id instrumentation tags every background inference so a runaway driver can be pinned from recorded state rather than guessed (Rule 14).
FEATAutonomy is not permission. The Agents page now states plainly that raising autonomy does not grant new authority (F22).
CHOREAll-in on shaping: guard exhaustion never substitutes a canned message. When a guard chain exhausts, the model's own content is delivered through a single answer-fidelity delivery chokepoint; the now-dead canned-message helpers were removed. A correct answer is never discarded for a templated non-answer (F25).
CHORECapability-denial over-constrainer culled to observe-only. The reactive capability-denial guard is de-fanged to honesty-only (it suppresses no policy/sandbox/financial/prompt-leak guard) and logs every would-fire for the termination soak.
CHOREZero cloud budget degrades, it does not block. An autonomous turn with no cloud budget falls back to the free local route instead of hard-failing (educate, don't forbid).
CHORERemoved the dead `max_total_inference_seconds` knob — a misleading control that did nothing.
FIXHygiene writer-contention outage. A missing index made the agency-decisions hygiene sweep hold the single serialized writer for 57–84s, stalling every subsystem behind it. Indexed `agency_decisions(candidate_id, outcome)`; the sweep is now sub-second.
FIXStartup-stall outage (2026-06-26 RCA). The per-turn diagnostic trail, the demoted memory tier, and `pipeline_traces`/`model_selection_events` grew unbounded, so boot-time hygiene stalled. All are now age-capped.
FIXSession expiry keyed on real activity. Stale-active-session expiry now keys on the last real turn/message, not `updated_at` (which only moves on archive), so an old-but-actively-used conversation is never severed.
FIXObsidian vault scan can no longer hang the boot. A vault path on a TCC-gated / iCloud / hung filesystem blocked `os.OpenFile` indefinitely and bricked the daemon boot; the scan is now bounded by a boot timeout and the optional vault provider is skipped if it exceeds it.
FIXCircuit breaker recovers on provider health and no longer trips on a local model load timeout (cold-start latency is not a provider fault).
FIXTurn-timeout no longer dead-ends with a canned giveup, and a local-model timeout is no longer misattributed to a network/credit failure — the failure presenter tells the truth about what happened.
FIXConversation mode no longer hides a truthful status. The suppress-then-strip path stopped swallowing honest short answers, and short diagnostic questions classify as questions, not conversational filler (#9).
FIX`/status` reports the configured and the executing model distinctly, so a fallback in effect is visible rather than masked.
FIXEmbedder activation is honest (F4). An unresolved `embedding_provider` maps to the bundled embedder (engine included) instead of silently dropping to the n-gram floor, and a canceled caller context no longer triggers a false n-gram fallback or misreported failure.
FIX`disabled_bundled_providers` is honored authoritatively (F12) — a disabled provider is dropped from routing candidates and the fallback chain and stops appearing in `/api/health`.
FIXBundled-chat provider honors `ROBOTICUS_CHAT_SIDECAR_PORT`, matching the sidecar spawn, so a co-located instance's inference no longer dials the wrong port (release soak-gate blocker).
FIXA keyless fallback provider warns instead of silently being an unusable routing entry.
FIXLive model-swap repoints `models.primary` to the new gguf (F10) so the swap takes effect, and context-overflow returns an honest error while restart reports the new pid (F14).
FIXInstaller correctness (I3/I4/I5): SELinux exec context, systemd `User`/`HOME`, and a sane `RestartSec`; the upgrade now guarantees the replaced binary is OS-launchable on the target platform.
FIXAgency and mechanic honesty. Autonomous turns bind to the explicit bundled-local route; the workspace and grounding judges skip when the call routes local (storm fix, P0); mechanic security posture comes from one shared auditor (no more false green); `agent.delegation_enabled` actually gates dispatch; and orchestrate-subagents reaches a terminal state and tells the truth (#20).
FIXDashboard / UX. Agency confirmation reads as a confirm step, not a blocking error (F21); the Agents-page Autonomy/Agency slider no longer navigates away (F20); Integrations show compact one-line channel rows with inline TEST.
FIXHonest logs and visible denials. Walletless install logs INFO, not ERROR (F13); a non-allowlisted sender's denial is visible, not a silent DEBUG drop; the channel health view checks the keystore key the daemon actually uses (no false `missing_token_ref` for Telegram).
FIX`sessions list` routes through the daemon (honoring `--url`, fail-loud) instead of a silent direct DB read; `mechanic check` gives an honest primary-provider verdict; revenue LIST no longer 500s on unsettled (NULL settlement) rows.
FIXPer-turn `context_snapshots` are written so memory analytics are no longer blind, and no post-success model re-runs fire on a slow local route (F28 wedge).
FIX`columns_json` tolerates both formats, killing ~13 false "deserialize" warnings at boot.

v1.3.6

Bug Fixes & Stability (16 changes)2026-06-25

Added: 3 changes. Fixed: 13 changes. Key changes: Bundled llama.cpp chat sidecar is the local-first default provider. `roboticus setup` now offers `bundled` first and as the default (local model, no API key, no Ollama), routing the primary to the bundled chat sidecar; README and dashboard provider colors align to the bundled runtime. Local-first onboarding with no separate install. Localized prefer-local for autonomous turns. `AgencyConfig.PreferLocalModel` (default on) routes agency-delegated turns to a free local model with cloud fallback, scoped strictly to autonomous turns so it never downgrades an interactive user turn. Mandatory `request_tools` + `recall_memory` tool-surface floor. These two tools are now on the surface of every turn, never prunable by any envelope (lightweight, focused, truncated, or read-only). Recorded production showed `request_tools` denied 372x while the surface-widen signal was ignored, making tool-starvation an unrecoverable lockout; a failing test proved the v1.3.5 widen did not cover it. x402 micropayment no longer hijacks any HTTP 402. A standard keyed provider's 402 ("out of credits") was misread as a crypto micropayment request and attempted an on-chain wallet payment. x402 is now gated to providers explicitly opted in (`x402_enabled`); every other 402 maps to an honest "out of credits".

Highlights

  • Bundled llama.cpp chat sidecar is the local-first default provider. `roboticus setup` now offers `bundled` first and as the default (local model, no API key, no Ollama), routing the primary to the bundled chat sidecar; README and dashboard provider colors align to the bundled runtime. Local-first onboarding with no separate install.
  • Localized prefer-local for autonomous turns. `AgencyConfig.PreferLocalModel` (default on) routes agency-delegated turns to a free local model with cloud fallback, scoped strictly to autonomous turns so it never downgrades an interactive user turn.
  • `roboticus status` shows the binary version.
  • Mandatory `request_tools` + `recall_memory` tool-surface floor. These two tools are now on the surface of every turn, never prunable by any envelope (lightweight, focused, truncated, or read-only). Recorded production showed `request_tools` denied 372x while the surface-widen signal was ignored, making tool-starvation an unrecoverable lockout; a failing test proved the v1.3.5 widen did not cover it.
  • x402 micropayment no longer hijacks any HTTP 402. A standard keyed provider's 402 ("out of credits") was misread as a crypto micropayment request and attempted an on-chain wallet payment. x402 is now gated to providers explicitly opted in (`x402_enabled`); every other 402 maps to an honest "out of credits".
  • Soft self-healing cron circuit-breaker. A failing job's `consecutive_errors` was never incremented, so it re-fired forever. After repeated failures a job now backs off with an exponential, capped cooldown and self-heals on its next success, a soft degradation rather than a permanent disable.
  • Real one-shot cron semantics. A "run once" task now runs exactly once (`now`/ISO-timestamp resolves to a self-disabling one-shot) instead of persisting as a recurring `* * * * *` job.
  • Agency harvester no longer records trivial acknowledgements or timestamp stubs as unresolved questions, ending the per-tick "unresolved: sure" treadmill.
FEATBundled llama.cpp chat sidecar is the local-first default provider. `roboticus setup` now offers `bundled` first and as the default (local model, no API key, no Ollama), routing the primary to the bundled chat sidecar; README and dashboard provider colors align to the bundled runtime. Local-first onboarding with no separate install.
FEATLocalized prefer-local for autonomous turns. `AgencyConfig.PreferLocalModel` (default on) routes agency-delegated turns to a free local model with cloud fallback, scoped strictly to autonomous turns so it never downgrades an interactive user turn.
FEAT`roboticus status` shows the binary version.
FIXMandatory `request_tools` + `recall_memory` tool-surface floor. These two tools are now on the surface of every turn, never prunable by any envelope (lightweight, focused, truncated, or read-only). Recorded production showed `request_tools` denied 372x while the surface-widen signal was ignored, making tool-starvation an unrecoverable lockout; a failing test proved the v1.3.5 widen did not cover it.
FIXx402 micropayment no longer hijacks any HTTP 402. A standard keyed provider's 402 ("out of credits") was misread as a crypto micropayment request and attempted an on-chain wallet payment. x402 is now gated to providers explicitly opted in (`x402_enabled`); every other 402 maps to an honest "out of credits".
FIXSoft self-healing cron circuit-breaker. A failing job's `consecutive_errors` was never incremented, so it re-fired forever. After repeated failures a job now backs off with an exponential, capped cooldown and self-heals on its next success, a soft degradation rather than a permanent disable.
FIXReal one-shot cron semantics. A "run once" task now runs exactly once (`now`/ISO-timestamp resolves to a self-disabling one-shot) instead of persisting as a recurring `* * * * *` job.
FIXAgency harvester no longer records trivial acknowledgements or timestamp stubs as unresolved questions, ending the per-tick "unresolved: sure" treadmill.
FIXScheduler-evidence projection augments, never overwrites a correct model answer.
FIXBundled embedder is a validated hard default — `bundled-embedder` resolves to the daemon sidecar (validated like the daemon's own bind), with an honest n-gram fallback, instead of silently degrading.
FIXSoak-port isolation — release soaks no longer grab a co-located production instance's bundled sidecar ports.
FIXHonest local-activation banner — the models page no longer claims a model "is being activated locally now" while the supervisor is degraded; it points to the Local runtime health card.
FIXBundled `llama-server` ships executable + the daemon self-heals the exec bit. The bundled binary was installed/upgraded without the exec bit (0644), so the chat/embedder sidecar spawn failed "permission denied" and the local runtime silently degraded to cloud/n-gram — unrecoverable by re-pin, enable, toggle, or even a daemon restart. The install/upgrade now marks anything under `bin/` executable, and the daemon re-asserts the bit (chmod +x) on every sidecar launch.
FIXBundled chat sidecar context raised to 16384 so the local route fits real agent prompts (~13–14k tokens); the prior 8192 rejected real turns with HTTP 400 "exceeds context size".
FIXBundled sidecar threads scale to the hardware. The chat sidecar was pinned to a fixed 4 threads regardless of host size or model, so a large model on a many-core host (a 30B on a 32-core server) could not finish a turn before the inference deadline and the bundled-chat breaker opened. Each sidecar now takes a named share of the host's physical cores (chat 75%, embedder 25%, partitioning the box; llama.cpp gains nothing from SMT siblings), floored at one thread and capped by the cgroup-aware CPU budget so a CPU-limited container can't oversubscribe; `models.local_chat_host.threads` overrides per host, re-resolved on a runtime model swap.
FIXGrounding judge fails open when it cannot render a verdict (provider error, timeout, or an unparseable reply) — it now keeps the model's honest content instead of suppressing it behind a canned message. A live greeting was canned because the judge returned "unparseable verdict" twice; the hard-safety guard net is re-checked separately and is never reached by this fail-open.

v1.3.5

Bug Fixes & Stability2026-06-24

Fixed: 2 changes. Key changes: Tool-envelope starvation: the model's withheld-tool need is now honored. The per-turn tool classifier routes subagent/action turns to narrow focused envelopes that withheld the action tools (`write_file`/`edit_file`/`orchestrate-subagents`) — a `focused_delegation` envelope even shipped zero orchestration tools while its reason claimed to retain them. When the model deliberately reached for a real registered tool it was hard-blocked for the whole turn (the framework's own grounding judge twice certified the model was truthfully blocked and the surface genuinely starved). Root: the widen valve fired only for light-budget envelopes and `Expanded()` no-op'd otherwise, so a narrow focused envelope could never recover a withheld tool. Now any narrow per-turn surface widens when the model signals it reached for a withheld real tool — dropping the focused profile + cap so the full ranked surface (including the blocked tool) is admitted on the retry. The model's correct cognition overrides the classifier's surface guess. `internal/pipeline/turn_policy.go`, `internal/pipeline/pipeline_stages_envelope.go`. Inbound injection sanitizer no longer corrupts legitimate operator input. The L2 redaction pattern `you are now [^.\n]+` matched a benign operator message ("see if you are now able to do some of the stuff you were previously blocked on") and ate the rest of the clause, replacing it with `[REDACTED]` before the model ran. L2 now gates on an actual persona-swap target (unrestricted/jailbroken/DAN/admin/dev-mode/…), mirroring the already-tight L4 patterns; real jailbreaks still redact. `internal/agent/injection.go`.

Highlights

  • Tool-envelope starvation: the model's withheld-tool need is now honored. The per-turn tool classifier routes subagent/action turns to narrow focused envelopes that withheld the action tools (`write_file`/`edit_file`/`orchestrate-subagents`) — a `focused_delegation` envelope even shipped zero orchestration tools while its reason claimed to retain them. When the model deliberately reached for a real registered tool it was hard-blocked for the whole turn (the framework's own grounding judge twice certified the model was truthfully blocked and the surface genuinely starved). Root: the widen valve fired only for light-budget envelopes and `Expanded()` no-op'd otherwise, so a narrow focused envelope could never recover a withheld tool. Now any narrow per-turn surface widens when the model signals it reached for a withheld real tool — dropping the focused profile + cap so the full ranked surface (including the blocked tool) is admitted on the retry. The model's correct cognition overrides the classifier's surface guess. `internal/pipeline/turn_policy.go`, `internal/pipeline/pipeline_stages_envelope.go`.
  • Inbound injection sanitizer no longer corrupts legitimate operator input. The L2 redaction pattern `you are now [^.\n]+` matched a benign operator message ("see if you are now able to do some of the stuff you were previously blocked on") and ate the rest of the clause, replacing it with `[REDACTED]` before the model ran. L2 now gates on an actual persona-swap target (unrestricted/jailbroken/DAN/admin/dev-mode/…), mirroring the already-tight L4 patterns; real jailbreaks still redact. `internal/agent/injection.go`.
FIXTool-envelope starvation: the model's withheld-tool need is now honored. The per-turn tool classifier routes subagent/action turns to narrow focused envelopes that withheld the action tools (`write_file`/`edit_file`/`orchestrate-subagents`) — a `focused_delegation` envelope even shipped zero orchestration tools while its reason claimed to retain them. When the model deliberately reached for a real registered tool it was hard-blocked for the whole turn (the framework's own grounding judge twice certified the model was truthfully blocked and the surface genuinely starved). Root: the widen valve fired only for light-budget envelopes and `Expanded()` no-op'd otherwise, so a narrow focused envelope could never recover a withheld tool. Now any narrow per-turn surface widens when the model signals it reached for a withheld real tool — dropping the focused profile + cap so the full ranked surface (including the blocked tool) is admitted on the retry. The model's correct cognition overrides the classifier's surface guess. `internal/pipeline/turn_policy.go`, `internal/pipeline/pipeline_stages_envelope.go`.
FIXInbound injection sanitizer no longer corrupts legitimate operator input. The L2 redaction pattern `you are now [^.\n]+` matched a benign operator message ("see if you are now able to do some of the stuff you were previously blocked on") and ate the rest of the clause, replacing it with `[REDACTED]` before the model ran. L2 now gates on an actual persona-swap target (unrestricted/jailbroken/DAN/admin/dev-mode/…), mirroring the already-tight L4 patterns; real jailbreaks still redact. `internal/agent/injection.go`.

v1.3.4

Bug Fixes & Stability & More2026-06-24

Fixed: 3 changes. Removed: 1 change. Changed: 3 changes. Added: 1 change. Key changes: The canned "we held this back" non-answer no longer overwrites a forgiven answer. When the grounding judge forgives a behavioral-guard rejection as honest grounded content, the retry signal is now cleared at the source, so neither exhaustion handler (post-success or verifier) fail-closes over the real answer. RCA `introspection_discovery`, pinned from recorded state via new soak instrumentation: `task_deferral` mis-fired "action-bearing turn finalized without action-specific tool evidence" on a read-only introspection turn, exhausted, and buried the model's real subagent summary under the canned line even though the judge had forgiven it. Genuine deferrals (scheduling) and non-forgivable hard-safety guards (false capability denials, financial/filesystem/config) still fail-closed. `internal/pipeline/guard_retry.go`. Forgiveness cannot disable a co-occurring hard-safety fail-closed. The guard chain short-circuits at the first retry guard, so when a forgivable guard fires first, a hard-safety guard registered later (financial/execution/filesystem) never runs. Forgiveness now re-validates the content against the non-forgivable hard-safety guards before clearing the retry; if any would fire, the turn fails closed. This closes an ABORT-premortem dealbreaker: a financial fabrication on a turn that also tripped a forgivable guard could otherwise have shipped. `internal/pipeline/guard_context.go` (`anyHardSafetyGuardFires`). Eliminated the `named_topic_continuity` exact-match guard. It retried any return-to-topic answer that did not contain the literal session topic anchor (`strings.Contains`), so a semantically-correct answer phrased differently was retried to exhaustion, a brittle exact-match that flipped run-to-run. Deleted (not de-fanged), with its anchor helpers and context field; the full guard chain drops 16 → 15. Bundled local chat host runs serial (1 slot). The RAM-tiered parallel slots (1/2/3 by RAM) are removed: RAM is not the bottleneck for parallel local inference, compute is, so N "parallel" slots split one CPU-bound model N ways and a concurrent burst made one turn exceed its inference deadline. The host now runs one inference at a time (`llm.SidecarChatSlots = 1`, the single source of truth for llama-server `--parallel` and the provider's `MaxConcurrency`); concurrent turns queue client-side and complete reliably at full speed.

Highlights

  • The canned "we held this back" non-answer no longer overwrites a forgiven answer. When the grounding judge forgives a behavioral-guard rejection as honest grounded content, the retry signal is now cleared at the source, so neither exhaustion handler (post-success or verifier) fail-closes over the real answer. RCA `introspection_discovery`, pinned from recorded state via new soak instrumentation: `task_deferral` mis-fired "action-bearing turn finalized without action-specific tool evidence" on a read-only introspection turn, exhausted, and buried the model's real subagent summary under the canned line even though the judge had forgiven it. Genuine deferrals (scheduling) and non-forgivable hard-safety guards (false capability denials, financial/filesystem/config) still fail-closed. `internal/pipeline/guard_retry.go`.
  • Forgiveness cannot disable a co-occurring hard-safety fail-closed. The guard chain short-circuits at the first retry guard, so when a forgivable guard fires first, a hard-safety guard registered later (financial/execution/filesystem) never runs. Forgiveness now re-validates the content against the non-forgivable hard-safety guards before clearing the retry; if any would fire, the turn fails closed. This closes an ABORT-premortem dealbreaker: a financial fabrication on a turn that also tripped a forgivable guard could otherwise have shipped. `internal/pipeline/guard_context.go` (`anyHardSafetyGuardFires`).
  • An `output_contract` fail-closed now names what the contract required, not the generic canned line. `output_contract` is intentionally non-forgivable (its boundaries are absolute), so the grounding-judge retry-clear above does not reach it; when it does block (e.g. a blocked-interruption follow-up that omits whether the blocked write changed the recommendation), the message now states the specific requirement instead of "we held this back." A systemic reconsideration of `output_contract`'s absoluteness / the broader canned substitution is on the roadmap for the next point release. `internal/pipeline/post_success_retry_policy.go`.
  • Eliminated the `named_topic_continuity` exact-match guard. It retried any return-to-topic answer that did not contain the literal session topic anchor (`strings.Contains`), so a semantically-correct answer phrased differently was retried to exhaustion, a brittle exact-match that flipped run-to-run. Deleted (not de-fanged), with its anchor helpers and context field; the full guard chain drops 16 → 15.
  • Bundled local chat host runs serial (1 slot). The RAM-tiered parallel slots (1/2/3 by RAM) are removed: RAM is not the bottleneck for parallel local inference, compute is, so N "parallel" slots split one CPU-bound model N ways and a concurrent burst made one turn exceed its inference deadline. The host now runs one inference at a time (`llm.SidecarChatSlots = 1`, the single source of truth for llama-server `--parallel` and the provider's `MaxConcurrency`); concurrent turns queue client-side and complete reliably at full speed.
  • Behavioral soak: guard-violation instrumentation + de-exact-matched checks. The soak now records the firing guard's violations and reasons, so a failure is pinned to the exact guard without the cleaned clone DB (the gap that blocked the `introspection_discovery` RCA). The introspection and topic-anchor continuity checks no longer require literal marker/anchor strings; they assert the same intent semantically, so a correct answer phrased differently is no longer failed.
  • Behavioral soak: compact web bodies count as source evidence. The fresh-external-info check classified a real but terse `http_fetch` body (e.g. wttr.in `Sunny +25°C 8km/h 57%`) as "URL/status-only" because it required a 40+ char line or a hardcoded keyword, an answer-fidelity false-negative that failed a correct, grounded weather answer. The check now skips the `HTTP <code>` header line and treats a non-header body line carrying concrete data (a digit alongside letters) as value-bearing; genuine status-only reads are still rejected. An HTTP-200 error/interstitial body (404 text, rate-limit JSON, JS/captcha challenge) is NOT source evidence, so a fabricated answer over a failed fetch cannot score green (ABORT fix).
  • `roboticus mechanic` shows the binary version in a muted line below the banner.
FIXThe canned "we held this back" non-answer no longer overwrites a forgiven answer. When the grounding judge forgives a behavioral-guard rejection as honest grounded content, the retry signal is now cleared at the source, so neither exhaustion handler (post-success or verifier) fail-closes over the real answer. RCA `introspection_discovery`, pinned from recorded state via new soak instrumentation: `task_deferral` mis-fired "action-bearing turn finalized without action-specific tool evidence" on a read-only introspection turn, exhausted, and buried the model's real subagent summary under the canned line even though the judge had forgiven it. Genuine deferrals (scheduling) and non-forgivable hard-safety guards (false capability denials, financial/filesystem/config) still fail-closed. `internal/pipeline/guard_retry.go`.
FIXForgiveness cannot disable a co-occurring hard-safety fail-closed. The guard chain short-circuits at the first retry guard, so when a forgivable guard fires first, a hard-safety guard registered later (financial/execution/filesystem) never runs. Forgiveness now re-validates the content against the non-forgivable hard-safety guards before clearing the retry; if any would fire, the turn fails closed. This closes an ABORT-premortem dealbreaker: a financial fabrication on a turn that also tripped a forgivable guard could otherwise have shipped. `internal/pipeline/guard_context.go` (`anyHardSafetyGuardFires`).
FIXAn `output_contract` fail-closed now names what the contract required, not the generic canned line. `output_contract` is intentionally non-forgivable (its boundaries are absolute), so the grounding-judge retry-clear above does not reach it; when it does block (e.g. a blocked-interruption follow-up that omits whether the blocked write changed the recommendation), the message now states the specific requirement instead of "we held this back." A systemic reconsideration of `output_contract`'s absoluteness / the broader canned substitution is on the roadmap for the next point release. `internal/pipeline/post_success_retry_policy.go`.
CHOREEliminated the `named_topic_continuity` exact-match guard. It retried any return-to-topic answer that did not contain the literal session topic anchor (`strings.Contains`), so a semantically-correct answer phrased differently was retried to exhaustion, a brittle exact-match that flipped run-to-run. Deleted (not de-fanged), with its anchor helpers and context field; the full guard chain drops 16 → 15.
CHOREBundled local chat host runs serial (1 slot). The RAM-tiered parallel slots (1/2/3 by RAM) are removed: RAM is not the bottleneck for parallel local inference, compute is, so N "parallel" slots split one CPU-bound model N ways and a concurrent burst made one turn exceed its inference deadline. The host now runs one inference at a time (`llm.SidecarChatSlots = 1`, the single source of truth for llama-server `--parallel` and the provider's `MaxConcurrency`); concurrent turns queue client-side and complete reliably at full speed.
CHOREBehavioral soak: guard-violation instrumentation + de-exact-matched checks. The soak now records the firing guard's violations and reasons, so a failure is pinned to the exact guard without the cleaned clone DB (the gap that blocked the `introspection_discovery` RCA). The introspection and topic-anchor continuity checks no longer require literal marker/anchor strings; they assert the same intent semantically, so a correct answer phrased differently is no longer failed.
CHOREBehavioral soak: compact web bodies count as source evidence. The fresh-external-info check classified a real but terse `http_fetch` body (e.g. wttr.in `Sunny +25°C 8km/h 57%`) as "URL/status-only" because it required a 40+ char line or a hardcoded keyword, an answer-fidelity false-negative that failed a correct, grounded weather answer. The check now skips the `HTTP <code>` header line and treats a non-header body line carrying concrete data (a digit alongside letters) as value-bearing; genuine status-only reads are still rejected. An HTTP-200 error/interstitial body (404 text, rate-limit JSON, JS/captcha challenge) is NOT source evidence, so a fabricated answer over a failed fetch cannot score green (ABORT fix).
FEAT`roboticus mechanic` shows the binary version in a muted line below the banner.

v1.3.2

Bug Fixes & Stability2026-06-23

Fixed: 2 changes. Key changes: Content-pack refresh was a silent dead channel.The upgrade client decided pack freshness by `installed.Version == manifest.Version`, and the registry manifest's top-level `version` was frozen at `0.11.0` for several releases — so `roboticus upgrade all` printed "pack already at version 0.11.0", skipped the fetch, and reported success while leaving providers, skills, and product-knowledge stale. The refresh decision now compares the manifest'sper-pack `sha256` (and per-file hashes for skills) against the installed content hash — both already present — so a changed pack is fetched and an unchanged one is skipped without download. Fixed in both the outer pack-selection gate and the inner product-knowledge gate (which short-circuited on the version before downloading). Verified that the live manifest regenerates per-pack hashes from current content, so the gate is sufficient with no site-side change. Upgrade download timeout hardened. Large asset/binary downloads (tens of MB) use a generous-timeout HTTP client instead of the 30s total timeout intended for small JSON metadata, which could abort an in-progress download on a slow link ("context deadline exceeded while reading body").

Highlights

  • Content-pack refresh was a silent dead channel.The upgrade client decided pack freshness by `installed.Version == manifest.Version`, and the registry manifest's top-level `version` was frozen at `0.11.0` for several releases — so `roboticus upgrade all` printed "pack already at version 0.11.0", skipped the fetch, and reported success while leaving providers, skills, and product-knowledge stale. The refresh decision now compares the manifest'sper-pack `sha256` (and per-file hashes for skills) against the installed content hash — both already present — so a changed pack is fetched and an unchanged one is skipped without download. Fixed in both the outer pack-selection gate and the inner product-knowledge gate (which short-circuited on the version before downloading). Verified that the live manifest regenerates per-pack hashes from current content, so the gate is sufficient with no site-side change.
  • Upgrade download timeout hardened. Large asset/binary downloads (tens of MB) use a generous-timeout HTTP client instead of the 30s total timeout intended for small JSON metadata, which could abort an in-progress download on a slow link ("context deadline exceeded while reading body").
FIXContent-pack refresh was a silent dead channel.The upgrade client decided pack freshness by `installed.Version == manifest.Version`, and the registry manifest's top-level `version` was frozen at `0.11.0` for several releases — so `roboticus upgrade all` printed "pack already at version 0.11.0", skipped the fetch, and reported success while leaving providers, skills, and product-knowledge stale. The refresh decision now compares the manifest'sper-pack `sha256` (and per-file hashes for skills) against the installed content hash — both already present — so a changed pack is fetched and an unchanged one is skipped without download. Fixed in both the outer pack-selection gate and the inner product-knowledge gate (which short-circuited on the version before downloading). Verified that the live manifest regenerates per-pack hashes from current content, so the gate is sufficient with no site-side change.
FIXUpgrade download timeout hardened. Large asset/binary downloads (tens of MB) use a generous-timeout HTTP client instead of the 30s total timeout intended for small JSON metadata, which could abort an in-progress download on a slow link ("context deadline exceeded while reading body").

v1.3.1

Bug Fixes & Stability2026-06-23

Fixed: 2 changes. Changed: 1 change. Key changes: Bundled chat host dropped forced-tool-call turns. The small bundled model returns prose instead of a tool call under `tool_choice=required`, which the framework treated as a provider failure (HTTP 500, dropped turn). The bundled chat provider now declares `RejectRequiredToolChoice` (the handling Ollama-format local models already get), so the framework degrades to automatic tool choice instead of failing. Also protects sub-agents routed to the local host. (Root cause confirmed from preserved soak evidence, correcting an earlier concurrency misdiagnosis.). Concurrent local-host turns could time out. The host ran a single llama-server slot, so concurrent turns (sub-agent fan-out, multiple channels) serialized and the over-queued turn could exceed the client timeout. The host now serves multiple parallel slots scaled to system RAM (`SidecarChatParallelSlots`; a constrained or detection-failed host keeps one slot, no memory regression), with `--ctx-size` scaled per slot, and the client caps in-flight requests per provider (`Provider.MaxConcurrency`) so overflow queues client-side instead of failing. The `local-chat-host` soak runner uses the product's real per-turn timeout (300s) and preserves the daemon log + per-turn responses into the report dir, so failures are diagnosable from recorded state (Rule 14) instead of vanishing with temp dirs.

Highlights

  • Bundled chat host dropped forced-tool-call turns. The small bundled model returns prose instead of a tool call under `tool_choice=required`, which the framework treated as a provider failure (HTTP 500, dropped turn). The bundled chat provider now declares `RejectRequiredToolChoice` (the handling Ollama-format local models already get), so the framework degrades to automatic tool choice instead of failing. Also protects sub-agents routed to the local host. (Root cause confirmed from preserved soak evidence, correcting an earlier concurrency misdiagnosis.)
  • Concurrent local-host turns could time out. The host ran a single llama-server slot, so concurrent turns (sub-agent fan-out, multiple channels) serialized and the over-queued turn could exceed the client timeout. The host now serves multiple parallel slots scaled to system RAM (`SidecarChatParallelSlots`; a constrained or detection-failed host keeps one slot, no memory regression), with `--ctx-size` scaled per slot, and the client caps in-flight requests per provider (`Provider.MaxConcurrency`) so overflow queues client-side instead of failing.
  • The `local-chat-host` soak runner uses the product's real per-turn timeout (300s) and preserves the daemon log + per-turn responses into the report dir, so failures are diagnosable from recorded state (Rule 14) instead of vanishing with temp dirs.
FIXBundled chat host dropped forced-tool-call turns. The small bundled model returns prose instead of a tool call under `tool_choice=required`, which the framework treated as a provider failure (HTTP 500, dropped turn). The bundled chat provider now declares `RejectRequiredToolChoice` (the handling Ollama-format local models already get), so the framework degrades to automatic tool choice instead of failing. Also protects sub-agents routed to the local host. (Root cause confirmed from preserved soak evidence, correcting an earlier concurrency misdiagnosis.)
FIXConcurrent local-host turns could time out. The host ran a single llama-server slot, so concurrent turns (sub-agent fan-out, multiple channels) serialized and the over-queued turn could exceed the client timeout. The host now serves multiple parallel slots scaled to system RAM (`SidecarChatParallelSlots`; a constrained or detection-failed host keeps one slot, no memory regression), with `--ctx-size` scaled per slot, and the client caps in-flight requests per provider (`Provider.MaxConcurrency`) so overflow queues client-side instead of failing.
CHOREThe `local-chat-host` soak runner uses the product's real per-turn timeout (300s) and preserves the daemon log + per-turn responses into the report dir, so failures are diagnosable from recorded state (Rule 14) instead of vanishing with temp dirs.

v1.3.0

New Features & More2026-06-22

Added: 8 changes. Fixed: 11 changes. Changed: 2 changes. Removed: 1 change. Key changes: Local LLM chat host (bundled, no Ollama). The bundled `llama.cpp` sidecar (embeddings-only in v1.2.0) is now a first-class local chat backend: Roboticus serves a local model with no separate install. External `llama.cpp`/Ollama and cloud providers remain first-class peers. Dedicated Models page (Local-runtime, Catalog, Providers, Routing, Comparison) with a HuggingFace install flow: discover a repo, list its GGUF files, fit-check against the real download size, and install any quant (content-hash pinned, SHA256-verified on next start). `mechanic` braille spinner on work-bearing steps — the per-table row counts, both integrity checks, and the maintenance VACUUM now run under a braille spinner so a slow step shows activity instead of a frozen-looking terminal. The spinner is a no-op on non-TTY/`--json` output. Delegation now happens when explicitly requested. Root-caused a multi-layer defect where an instructed delegation never invoked `orchestrate-subagents`: the planner plans delegation from a semantic intent signal, the turn requires delegation evidence, pre-response shaping pins and steers the tool, and the tool-surface pruner force-includes the orchestration tool (it was pruned for low relevance to the task content). Validated across the authority ladder: operator delegates, peer honestly refuses.

Highlights

  • Local LLM chat host (bundled, no Ollama). The bundled `llama.cpp` sidecar (embeddings-only in v1.2.0) is now a first-class local chat backend: Roboticus serves a local model with no separate install. External `llama.cpp`/Ollama and cloud providers remain first-class peers.
  • Dedicated Models page (Local-runtime, Catalog, Providers, Routing, Comparison) with a HuggingFace install flow: discover a repo, list its GGUF files, fit-check against the real download size, and install any quant (content-hash pinned, SHA256-verified on next start).
  • Intelligent parallel compaction, live. Older history is compacted off the critical path into a proof-backed digest with a fact-preservation guarantee, then spliced gap-free into the live context to cut token cost. Enabled by default.
  • Execution-grounded coding benchmark. Grades models by running their code (sandboxed compile gate, property/fuzz oracle over 200 seeded inputs against an in-process reference, `gofmt`/`go vet`), never by LLM-judge. Graded task corpus from trivial to expert.
  • Per-use-case model recommendations. Up to 3 local and 3 cloud picks each for coding, general-assistant, and chatbot use, computed deterministically and routing-neutral. Router cold-start priors reseeded from real measurements (`models reseed-baselines`); guessed folklore removed.
  • The Mechanic — a deterministic, framework-native maintenance plane (database, workspace, configuration, plugins, skills, security) that validates skill/plugin/app definitions and can diagnose and fix them, surfacing exactly why a definition was being silently skipped.
  • Answer-fidelity inverse soak. Fixes known-correct answers and asserts the framework preserves them through the post-generation seams: a deterministic per-seam battery (~13k checks, no model) plus a live end-to-end runner. Both gated in the soak suite.
  • Release soak suite (`just soak-suite`). One-command serial behavioral gate against an isolated instance, atomic runner/case selection, a gated `local-chat-host` runner (the bundled host serves real generation with no cloud fallback), and no Ollama dependency in the gate.
FEATLocal LLM chat host (bundled, no Ollama). The bundled `llama.cpp` sidecar (embeddings-only in v1.2.0) is now a first-class local chat backend: Roboticus serves a local model with no separate install. External `llama.cpp`/Ollama and cloud providers remain first-class peers.
FEATDedicated Models page (Local-runtime, Catalog, Providers, Routing, Comparison) with a HuggingFace install flow: discover a repo, list its GGUF files, fit-check against the real download size, and install any quant (content-hash pinned, SHA256-verified on next start).
FEATIntelligent parallel compaction, live. Older history is compacted off the critical path into a proof-backed digest with a fact-preservation guarantee, then spliced gap-free into the live context to cut token cost. Enabled by default.
FEATExecution-grounded coding benchmark. Grades models by running their code (sandboxed compile gate, property/fuzz oracle over 200 seeded inputs against an in-process reference, `gofmt`/`go vet`), never by LLM-judge. Graded task corpus from trivial to expert.
FEATPer-use-case model recommendations. Up to 3 local and 3 cloud picks each for coding, general-assistant, and chatbot use, computed deterministically and routing-neutral. Router cold-start priors reseeded from real measurements (`models reseed-baselines`); guessed folklore removed.
FEATThe Mechanic — a deterministic, framework-native maintenance plane (database, workspace, configuration, plugins, skills, security) that validates skill/plugin/app definitions and can diagnose and fix them, surfacing exactly why a definition was being silently skipped.
FEATAnswer-fidelity inverse soak. Fixes known-correct answers and asserts the framework preserves them through the post-generation seams: a deterministic per-seam battery (~13k checks, no model) plus a live end-to-end runner. Both gated in the soak suite.
FEATRelease soak suite (`just soak-suite`). One-command serial behavioral gate against an isolated instance, atomic runner/case selection, a gated `local-chat-host` runner (the bundled host serves real generation with no cloud fallback), and no Ollama dependency in the gate.
FIX`mechanic` braille spinner on work-bearing steps — the per-table row counts, both integrity checks, and the maintenance VACUUM now run under a braille spinner so a slow step shows activity instead of a frozen-looking terminal. The spinner is a no-op on non-TTY/`--json` output.
FIXDelegation now happens when explicitly requested. Root-caused a multi-layer defect where an instructed delegation never invoked `orchestrate-subagents`: the planner plans delegation from a semantic intent signal, the turn requires delegation evidence, pre-response shaping pins and steers the tool, and the tool-surface pruner force-includes the orchestration tool (it was pruned for low relevance to the task content). Validated across the authority ladder: operator delegates, peer honestly refuses.
FIXOperator authority on local control surfaces. The dashboard, TUI, and CLI (loopback websocket control channel) resolve to operator authority via a dedicated control-surface mode, so privileged tools work from the operator's own surface; the remote HTTP API stays peer.
FIXScheduling (cron) tool-surfacing. The cron tool is force-included on a scheduling turn so the agent can actually create the job (it was pruned, same class as delegation).
FIXRouting: unscored local models rank lowest-priority and can no longer preempt a configured, capable route (an unscored, cold-start local floor was outranking the configured model).
FIXProvider Remove persists (a removed provider no longer reappears after reload).
FIXBreaker state never renders "unknown" (defaults to the real closed/open/half-open state).
FIXLocal-model recommendation honors the operator's metascore weights and states its rationale.
FIXObservability delegation view reads the table the orchestrator writes, so real delegations appear.
FIXSession thinking indicator (bouncing brain plus animated dots) restored during the wait.
FIXWindows test portability — config-path tests set `%USERPROFILE%` (not just `$HOME`), and the chat-sidecar test writes the `state.db` path as a TOML literal so a Windows path is not parsed as an escape sequence. 3-OS CI is green.
CHOREAgency authority controls moved from Settings to the Agents page, where agent autonomy belongs.
CHOREPer-turn diagnostics record the actual selected tool names (not a bare count), so a pruned required tool is provable from recorded state.
CHORELegacy `delegation_outcomes` table and path. The Observability delegation view reads `agent_delegation_outcomes` (what the orchestrator actually writes); the unread per-turn `delegation_outcomes` writer, query, and `/api/delegations` route are removed. Migration 074 drops the table.

v1.2.0

New Features & More2026-06-17

Added: 7 changes. Changed: 4 changes. Fixed: 3 changes. Security: 1 change. Key changes: Bundled nomic embedder sidecar — a daemon-supervised, GGUF-content-hash-pinned `llama.cpp` process serving `nomic-embed-text` on loopback, removing the external Ollama embedding dependency while keeping the main binary `CGO_ENABLED=0` static. It is the standing default for implicit installs. Autonomous x402 micropayments — wired on and gated fail-closed by a Money-typed `TreasuryPolicy` (per-payment cap + hourly/daily budgets via a spend ledger + minimum reserve). Dormant until a wallet + RPC + passphrase are configured. Self-custody `roboticus wallet import` signs from a user-supplied key. Centralized logging (`internal/core/logging.go`) with context-propagated correlation IDs and console/JSON format selection; the daemon no longer emits raw JSON logs into interactive command output. CLI install/upgrade/daemon-control surfaces adopt the design language. `guard_retry_count` now counts the actual number of guard-triggered re-inferences, including grounding-judge-mediated ones (was a flat 0/1).

Highlights

  • Bundled nomic embedder sidecar — a daemon-supervised, GGUF-content-hash-pinned `llama.cpp` process serving `nomic-embed-text` on loopback, removing the external Ollama embedding dependency while keeping the main binary `CGO_ENABLED=0` static. It is the standing default for implicit installs.
  • Autonomous x402 micropayments — wired on and gated fail-closed by a Money-typed `TreasuryPolicy` (per-payment cap + hourly/daily budgets via a spend ledger + minimum reserve). Dormant until a wallet + RPC + passphrase are configured. Self-custody `roboticus wallet import` signs from a user-supplied key.
  • Weak-model-floor honest-blocker guard — when a turn required a tool but produced no successful tool evidence and is neither a clarifying question nor a runtime-grounded blocker, it is converted into an honest blocker instead of a confabulation. Never fires when a tool succeeded.
  • Agent self-repair — an agent-invocable `mechanic_repair` tool plus `mechanic --fix` (alias of `--repair`) and bare `fix`/`repair` subcommands, all sharing one `internal/mechanic.RunDatabaseRepair` core.
  • Agent Task Tracking Board— a dashboard board underAgents → Tasks surfacing the durable `tasks` table (cron / revenue / agency) plus new conversational *work-output* tasks the agent produces, in three views: kanban(Agent Work | Durable lanes × status columns),list, and timeline. A post-turn pipeline hook records a work-output task when the turn executed a work-product operation — an artifact write, state change, or outbound action, classified by `OperationClass`, not by effort or step count — deduped per originating session and run off the response path (shortcut/cache turns never reach it). Migration 070 adds `tasks.origin_session_id`; a `tasks` WebSocket topic + grouped snapshot feed the UI; source and completed-age filters apply client-side.
  • Agency blocked-proposal notification — one deduped operator notification when the same proposal is blocked N consecutive evaluation cycles.
  • Linux Landlock sandbox enforcement — real `x/sys/unix` Landlock (ABI-clamped, re-exec shim, ENOSYS graceful degradation), opt-in via `sandbox.enabled`.
  • Centralized logging (`internal/core/logging.go`) with context-propagated correlation IDs and console/JSON format selection; the daemon no longer emits raw JSON logs into interactive command output. CLI install/upgrade/daemon-control surfaces adopt the design language.
FEATBundled nomic embedder sidecar — a daemon-supervised, GGUF-content-hash-pinned `llama.cpp` process serving `nomic-embed-text` on loopback, removing the external Ollama embedding dependency while keeping the main binary `CGO_ENABLED=0` static. It is the standing default for implicit installs.
FEATAutonomous x402 micropayments — wired on and gated fail-closed by a Money-typed `TreasuryPolicy` (per-payment cap + hourly/daily budgets via a spend ledger + minimum reserve). Dormant until a wallet + RPC + passphrase are configured. Self-custody `roboticus wallet import` signs from a user-supplied key.
FEATWeak-model-floor honest-blocker guard — when a turn required a tool but produced no successful tool evidence and is neither a clarifying question nor a runtime-grounded blocker, it is converted into an honest blocker instead of a confabulation. Never fires when a tool succeeded.
FEATAgent self-repair — an agent-invocable `mechanic_repair` tool plus `mechanic --fix` (alias of `--repair`) and bare `fix`/`repair` subcommands, all sharing one `internal/mechanic.RunDatabaseRepair` core.
FEATAgent Task Tracking Board— a dashboard board underAgents → Tasks surfacing the durable `tasks` table (cron / revenue / agency) plus new conversational *work-output* tasks the agent produces, in three views: kanban(Agent Work | Durable lanes × status columns),list, and timeline. A post-turn pipeline hook records a work-output task when the turn executed a work-product operation — an artifact write, state change, or outbound action, classified by `OperationClass`, not by effort or step count — deduped per originating session and run off the response path (shortcut/cache turns never reach it). Migration 070 adds `tasks.origin_session_id`; a `tasks` WebSocket topic + grouped snapshot feed the UI; source and completed-age filters apply client-side.
FEATAgency blocked-proposal notification — one deduped operator notification when the same proposal is blocked N consecutive evaluation cycles.
FEATLinux Landlock sandbox enforcement — real `x/sys/unix` Landlock (ABI-clamped, re-exec shim, ENOSYS graceful degradation), opt-in via `sandbox.enabled`.
CHORECentralized logging (`internal/core/logging.go`) with context-propagated correlation IDs and console/JSON format selection; the daemon no longer emits raw JSON logs into interactive command output. CLI install/upgrade/daemon-control surfaces adopt the design language.
CHORE`guard_retry_count` now counts the actual number of guard-triggered re-inferences, including grounding-judge-mediated ones (was a flat 0/1).
CHORECI: main-push tree-reuse gate (skips the redundant heavy matrix when the pushed tree already has genuinely-green CI; matrix-skipping runs are rejected so reuse never cites a run that tested nothing) and promotion-control tolerance of an in-progress develop CI run.
CHORERepo-wide ~500-line file / ~120-line function cap remediation: the behavioral core (`loop.go`, `ws.go`, `internal/pipeline`), `internal/daemon`, and the rest of the tree decomposed by responsibility (pure relocation + behavior-preserving helper extraction); audited to zero source god functions.
FIXCron creation-time validation at every write path (REST/WS/CLI and the agent `cron` tool): rejects a task-bearing job with `delivery_mode=none` (`db.ErrInvalidCronJob` → HTTP 400), forbids a `noop` briefing action, and normalizes `agent_id` to the configured agent.
FIXx402/EIP-3009 zero-nonce replay closed (fresh `crypto/rand` nonce, reject non-32-byte); `WaitForReceipt` treats a reverted tx (status 0) as failure; eth JSON-RPC unified into one `ethRPCCall` seam with a monotonic id.
FIXAnswer-fidelity defect class — the framework no longer discards, corrupts, or degrades a correct model answer between generation and delivery. A single `persistAssistantMessage` seam (non-cancellable context, deliver-but-flag, `assistant_persist_failed` diagnostic) closes a durable-history drop (`long_mixed`); a shared `agenttools.ToolOutputLacksReadableContent` filter stops raw Playwright/`[ref=eN]` tool noise being shipped as the answer; a substantial-synthesis exemption stops a grounding-guard false-positive from overwriting a synthesized sitrep; verifier retries are re-anchored to the current request so a retry can't answer a stale adjacent question; and compression hard-keeps load-bearing/quantitative tokens with rune-safe truncation. Adds `reflection_finalized`/`loop_terminal_selection` Rule-14 instrumentation. See the release notes for the full per-defect RCA.
FIXWhatsApp webhook fails closed (explicit dev opt-out); plugin download/extract budget caps; macOS sandbox no-op warns UNCONFINED; `ActionVerificationGuard` canonical-cents compare; wallet passphrase data-loss fix.

v1.1.6

Bug Fixes & Stability2026-06-14

Fixed: 1 change. Key changes: `upgrade`/`update all` no longer skips the voice-runtime refresh with `Warning: ... unsafe archive path "./"`. The voice-piper archive carries a `./` root entry (as most tar tools emit); the voice extract loops passed it straight into the shared `safeArchiveTarget`, which rejected `.` as unsafe — so the voice runtime never refreshed on any upgrade since v1.1.0. Root-entry handling now lives once in `safeArchiveTarget` (it reports the harmless archive root as a skip), so all three extract loops (skills, product-knowledge, voice tar/zip) treat it consistently; path-traversal rejection is unchanged.

Highlights

  • `upgrade`/`update all` no longer skips the voice-runtime refresh with `Warning: ... unsafe archive path "./"`. The voice-piper archive carries a `./` root entry (as most tar tools emit); the voice extract loops passed it straight into the shared `safeArchiveTarget`, which rejected `.` as unsafe — so the voice runtime never refreshed on any upgrade since v1.1.0. Root-entry handling now lives once in `safeArchiveTarget` (it reports the harmless archive root as a skip), so all three extract loops (skills, product-knowledge, voice tar/zip) treat it consistently; path-traversal rejection is unchanged.
FIX`upgrade`/`update all` no longer skips the voice-runtime refresh with `Warning: ... unsafe archive path "./"`. The voice-piper archive carries a `./` root entry (as most tar tools emit); the voice extract loops passed it straight into the shared `safeArchiveTarget`, which rejected `.` as unsafe — so the voice runtime never refreshed on any upgrade since v1.1.0. Root-entry handling now lives once in `safeArchiveTarget` (it reports the harmless archive root as a skip), so all three extract loops (skills, product-knowledge, voice tar/zip) treat it consistently; path-traversal rejection is unchanged.

v1.1.5

Security Hardening2026-06-14

Security: 2 changes. Changed: 3 changes. Key changes: Injection output-cap fails loud instead of silently dropping output. The v1.1.3 input DoS cap also made the L4 output scan score any tool/LLM output over 256 KB as a maximal threat, so a legitimately large clean output (a file read, a web fetch, an inbox summary) was either mislabeled `[Tool output filtered: potential injection detected]` or silently emptied. Output now has a separate 1 MiB cap and is scanned by a bounded prefix: a clean large output passes through, a real injection in the prefix is still caught, and an oversized output records an honest `tool_output_scan_truncated` event. The fail-closed input cap is unchanged — input and output are deliberately asymmetric. Positional instruction-override injections are now detected. `CheckInput` matched "ignore … previous" but not positional phrasings ("ignore everything above", "ignore the preceding", "ignore below" — HTML-entity-encoded included), which scored 0 and reached the model unsanitized. A positional-override pattern now scores them at least caution so they are redacted. Flaky tests eliminated across nine packages, and gated. A fixed `time.Sleep` followed by an assertion on async state was the top source of flaky CI. An audit of all 64 test-sleep sites converted the flaky ones to `assert.Eventually` polling (plus atomic watched-file writes, a load-invariant concurrency ratio, explicit eviction timestamps, and a size-detectable keystore change). A new CI guard (`scripts/check-test-sleeps.sh`) fails any PR that adds a `time.Sleep` to a test beyond the reviewed baseline, pointing authors at `assert.Eventually`. Adversarial-issue coverage is 0 gaps / 100%. Two new guard-edge regression scenarios, a systemic corpus fix (deferred/unshipped fixes are excluded until they ship), and justified out-of-scope classifications for non-behavioral fixes.

Highlights

  • Injection output-cap fails loud instead of silently dropping output. The v1.1.3 input DoS cap also made the L4 output scan score any tool/LLM output over 256 KB as a maximal threat, so a legitimately large clean output (a file read, a web fetch, an inbox summary) was either mislabeled `[Tool output filtered: potential injection detected]` or silently emptied. Output now has a separate 1 MiB cap and is scanned by a bounded prefix: a clean large output passes through, a real injection in the prefix is still caught, and an oversized output records an honest `tool_output_scan_truncated` event. The fail-closed input cap is unchanged — input and output are deliberately asymmetric.
  • Positional instruction-override injections are now detected. `CheckInput` matched "ignore … previous" but not positional phrasings ("ignore everything above", "ignore the preceding", "ignore below" — HTML-entity-encoded included), which scored 0 and reached the model unsanitized. A positional-override pattern now scores them at least caution so they are redacted.
  • Flaky tests eliminated across nine packages, and gated. A fixed `time.Sleep` followed by an assertion on async state was the top source of flaky CI. An audit of all 64 test-sleep sites converted the flaky ones to `assert.Eventually` polling (plus atomic watched-file writes, a load-invariant concurrency ratio, explicit eviction timestamps, and a size-detectable keystore change). A new CI guard (`scripts/check-test-sleeps.sh`) fails any PR that adds a `time.Sleep` to a test beyond the reviewed baseline, pointing authors at `assert.Eventually`.
  • Adversarial-issue coverage is 0 gaps / 100%. Two new guard-edge regression scenarios, a systemic corpus fix (deferred/unshipped fixes are excluded until they ship), and justified out-of-scope classifications for non-behavioral fixes.
  • The product-knowledge pack audit is now a mandatory release-checklist item, codified in `docs/contributing.md` and the release procedure.
FIXInjection output-cap fails loud instead of silently dropping output. The v1.1.3 input DoS cap also made the L4 output scan score any tool/LLM output over 256 KB as a maximal threat, so a legitimately large clean output (a file read, a web fetch, an inbox summary) was either mislabeled `[Tool output filtered: potential injection detected]` or silently emptied. Output now has a separate 1 MiB cap and is scanned by a bounded prefix: a clean large output passes through, a real injection in the prefix is still caught, and an oversized output records an honest `tool_output_scan_truncated` event. The fail-closed input cap is unchanged — input and output are deliberately asymmetric.
FIXPositional instruction-override injections are now detected. `CheckInput` matched "ignore … previous" but not positional phrasings ("ignore everything above", "ignore the preceding", "ignore below" — HTML-entity-encoded included), which scored 0 and reached the model unsanitized. A positional-override pattern now scores them at least caution so they are redacted.
CHOREFlaky tests eliminated across nine packages, and gated. A fixed `time.Sleep` followed by an assertion on async state was the top source of flaky CI. An audit of all 64 test-sleep sites converted the flaky ones to `assert.Eventually` polling (plus atomic watched-file writes, a load-invariant concurrency ratio, explicit eviction timestamps, and a size-detectable keystore change). A new CI guard (`scripts/check-test-sleeps.sh`) fails any PR that adds a `time.Sleep` to a test beyond the reviewed baseline, pointing authors at `assert.Eventually`.
CHOREAdversarial-issue coverage is 0 gaps / 100%. Two new guard-edge regression scenarios, a systemic corpus fix (deferred/unshipped fixes are excluded until they ship), and justified out-of-scope classifications for non-behavioral fixes.
CHOREThe product-knowledge pack audit is now a mandatory release-checklist item, codified in `docs/contributing.md` and the release procedure.

v1.1.4

New Features2026-06-13

Added: 1 change. Fixed: 1 change. Key changes: Read-only inbox-summarize capability (`read_inbox`): the agent reads recent messages from the configured mailbox via a read-only `ListRecent` (IMAP `SINCE` scope, `BODY.PEEK` so mail is never marked seen, bounded full bodies), registered only when IMAP email is configured. Live-verified against a Proton Bridge (5 real messages, read-only, no `state.db` touch). The agent answers with an honest limitation instead of exhausting its retry budget. RCA (production turn `696abbc9`): asked to act on an introspection-only turn (no action tools), it narrated future actions, the `task_deferral` guard rejected every attempt, and after six attempts it emitted the canned "couldn't get a confident answer." That exhaustion now yields an honest limitation answer ("only read-only introspection tools were available; enable the needed tool/capability"). Instrumentation: the blocked diagnostics name this case correctly, and `primary_diagnosis` is set on every blocked-exhaustion turn.

Highlights

  • Read-only inbox-summarize capability (`read_inbox`): the agent reads recent messages from the configured mailbox via a read-only `ListRecent` (IMAP `SINCE` scope, `BODY.PEEK` so mail is never marked seen, bounded full bodies), registered only when IMAP email is configured. Live-verified against a Proton Bridge (5 real messages, read-only, no `state.db` touch).
  • The agent answers with an honest limitation instead of exhausting its retry budget. RCA (production turn `696abbc9`): asked to act on an introspection-only turn (no action tools), it narrated future actions, the `task_deferral` guard rejected every attempt, and after six attempts it emitted the canned "couldn't get a confident answer." That exhaustion now yields an honest limitation answer ("only read-only introspection tools were available; enable the needed tool/capability"). Instrumentation: the blocked diagnostics name this case correctly, and `primary_diagnosis` is set on every blocked-exhaustion turn.
FEATRead-only inbox-summarize capability (`read_inbox`): the agent reads recent messages from the configured mailbox via a read-only `ListRecent` (IMAP `SINCE` scope, `BODY.PEEK` so mail is never marked seen, bounded full bodies), registered only when IMAP email is configured. Live-verified against a Proton Bridge (5 real messages, read-only, no `state.db` touch).
FIXThe agent answers with an honest limitation instead of exhausting its retry budget. RCA (production turn `696abbc9`): asked to act on an introspection-only turn (no action tools), it narrated future actions, the `task_deferral` guard rejected every attempt, and after six attempts it emitted the canned "couldn't get a confident answer." That exhaustion now yields an honest limitation answer ("only read-only introspection tools were available; enable the needed tool/capability"). Instrumentation: the blocked diagnostics name this case correctly, and `primary_diagnosis` is set on every blocked-exhaustion turn.

v1.1.3

Bug Fixes & Stability2026-06-12

Fixed: 4 changes. Changed: 3 changes. Key changes: Injection-detector unbounded-scan DoS: input over a 256 KB cap is treated as a threat and short-circuited before NFKC normalize + regex, instead of stalling the pipeline ~25s on a single oversized inbound message. Injection `Sanitize` HTML/percent-entity decode bypass: entity-encoded injections that `CheckInput` flags no longer survive sanitization unredacted. In-app `update all` / `upgrade all` gained `--version` to install, reinstall, or downgrade a specific release, matching `install.sh --version`. `install.sh` installs in place over an existing `roboticus` on PATH instead of hardcoding `/usr/local/bin`, so it can never shadow the self-updated binary.

Highlights

  • Injection-detector unbounded-scan DoS: input over a 256 KB cap is treated as a threat and short-circuited before NFKC normalize + regex, instead of stalling the pipeline ~25s on a single oversized inbound message.
  • Injection `Sanitize` HTML/percent-entity decode bypass: entity-encoded injections that `CheckInput` flags no longer survive sanitization unredacted.
  • `upgrade` no longer treats a `-dev` build as already current: the version comparator orders a prerelease below its same-base release, so a dev build upgrades to the real release.
  • `ghola` SSRF pre-flight no longer flakes CI on live DNS (bounded, injectable, fail-closed resolver); markdown-prose-asserting unit tests removed (their behavior assertions kept).
  • In-app `update all` / `upgrade all` gained `--version` to install, reinstall, or downgrade a specific release, matching `install.sh --version`.
  • `install.sh` installs in place over an existing `roboticus` on PATH instead of hardcoding `/usr/local/bin`, so it can never shadow the self-updated binary.
  • Release preflight reuses CI evidence keyed on the commit git-tree, not the commit SHA, eliminating a redundant full race re-run on code-identical content.
FIXInjection-detector unbounded-scan DoS: input over a 256 KB cap is treated as a threat and short-circuited before NFKC normalize + regex, instead of stalling the pipeline ~25s on a single oversized inbound message.
FIXInjection `Sanitize` HTML/percent-entity decode bypass: entity-encoded injections that `CheckInput` flags no longer survive sanitization unredacted.
FIX`upgrade` no longer treats a `-dev` build as already current: the version comparator orders a prerelease below its same-base release, so a dev build upgrades to the real release.
FIX`ghola` SSRF pre-flight no longer flakes CI on live DNS (bounded, injectable, fail-closed resolver); markdown-prose-asserting unit tests removed (their behavior assertions kept).
CHOREIn-app `update all` / `upgrade all` gained `--version` to install, reinstall, or downgrade a specific release, matching `install.sh --version`.
CHORE`install.sh` installs in place over an existing `roboticus` on PATH instead of hardcoding `/usr/local/bin`, so it can never shadow the self-updated binary.
CHORERelease preflight reuses CI evidence keyed on the commit git-tree, not the commit SHA, eliminating a redundant full race re-run on code-identical content.

v1.1.2

Bug Fixes & Stability & More2026-06-12

Fixed: 4 changes. Added: 1 change. Changed: 2 changes. Security: 1 change. Key changes: Inbound messages are no longer dropped on transient DB contention. The inbound dedup claim is an idempotency guard, but a claim error (a SQLITE_BUSY while a maintenance hygiene run held the single WAL writer) was treated as fatal and silently ate the user's message. It now FAILS OPEN — process the message and surface the failure — for every channel and every transient cause. The cron scheduler runs again. A non-nullable scan of `NULL schedule_every_ms` silently dropped every cron-expression job on every tick; production cron had not run since 2026-04-06. The scan is nullable and fails loud; legacy `cron_runs` columns are converged so the revived worker records run history. Email channel STARTTLS support for IMAP and SMTP, with configurable SMTP transport security (`smtp_security`). Enables a local mail bridge (e.g. Proton Bridge on 127.0.0.1) that advertises STARTTLS. `state.db` now uses a dedicated single-connection serialized writer pool plus a concurrent read pool, instead of one shared pool. Writes serialize on one connection (minimal lock-hold, smaller corruption window) while WAL readers run concurrently; the backup `VACUUM INTO` moved off the writer. In-memory databases keep a single shared handle.

Highlights

  • Inbound messages are no longer dropped on transient DB contention. The inbound dedup claim is an idempotency guard, but a claim error (a SQLITE_BUSY while a maintenance hygiene run held the single WAL writer) was treated as fatal and silently ate the user's message. It now FAILS OPEN — process the message and surface the failure — for every channel and every transient cause.
  • The cron scheduler runs again. A non-nullable scan of `NULL schedule_every_ms` silently dropped every cron-expression job on every tick; production cron had not run since 2026-04-06. The scan is nullable and fails loud; legacy `cron_runs` columns are converged so the revived worker records run history.
  • The maintenance lock-storm root cause is removed: an O(n^2) correlated-subquery hygiene dedup over un-indexed `working_memory` content held the WAL writer ~90s. It is now a single-scan window function.
  • SQLITE_BUSY is surfaced as honest transient contention instead of a generic "something went wrong".
  • Email channel STARTTLS support for IMAP and SMTP, with configurable SMTP transport security (`smtp_security`). Enables a local mail bridge (e.g. Proton Bridge on 127.0.0.1) that advertises STARTTLS.
  • `state.db` now uses a dedicated single-connection serialized writer pool plus a concurrent read pool, instead of one shared pool. Writes serialize on one connection (minimal lock-hold, smaller corruption window) while WAL readers run concurrently; the backup `VACUUM INTO` moved off the writer. In-memory databases keep a single shared handle.
  • Read-only agency action classes (observe/summarize/diagnose) are confined to read-only tools at execution. The action-class policy previously gated the decision but not the tool surface, so a `summarize` approval could (and did) call `orchestrate-subagents`/`retry-task` and spawn workflows.
  • A loopback mail bridge's self-signed certificate is verified with skip-verify for loopback hosts only (it cannot be MITM'd over the network); every remote mail host stays fully certificate-verified.
FIXInbound messages are no longer dropped on transient DB contention. The inbound dedup claim is an idempotency guard, but a claim error (a SQLITE_BUSY while a maintenance hygiene run held the single WAL writer) was treated as fatal and silently ate the user's message. It now FAILS OPEN — process the message and surface the failure — for every channel and every transient cause.
FIXThe cron scheduler runs again. A non-nullable scan of `NULL schedule_every_ms` silently dropped every cron-expression job on every tick; production cron had not run since 2026-04-06. The scan is nullable and fails loud; legacy `cron_runs` columns are converged so the revived worker records run history.
FIXThe maintenance lock-storm root cause is removed: an O(n^2) correlated-subquery hygiene dedup over un-indexed `working_memory` content held the WAL writer ~90s. It is now a single-scan window function.
FIXSQLITE_BUSY is surfaced as honest transient contention instead of a generic "something went wrong".
FEATEmail channel STARTTLS support for IMAP and SMTP, with configurable SMTP transport security (`smtp_security`). Enables a local mail bridge (e.g. Proton Bridge on 127.0.0.1) that advertises STARTTLS.
CHORE`state.db` now uses a dedicated single-connection serialized writer pool plus a concurrent read pool, instead of one shared pool. Writes serialize on one connection (minimal lock-hold, smaller corruption window) while WAL readers run concurrently; the backup `VACUUM INTO` moved off the writer. In-memory databases keep a single shared handle.
CHORERead-only agency action classes (observe/summarize/diagnose) are confined to read-only tools at execution. The action-class policy previously gated the decision but not the tool surface, so a `summarize` approval could (and did) call `orchestrate-subagents`/`retry-task` and spawn workflows.
FIXA loopback mail bridge's self-signed certificate is verified with skip-verify for loopback hosts only (it cannot be MITM'd over the network); every remote mail host stays fully certificate-verified.

v1.1.1

New Features & More2026-06-11

Fixed: 1 change. Added: 3 changes. Removed: 1 change. Key changes: The daemon now FAILS LOUD when its API address cannot bind (or the API server later terminates): previously it logged one error and kept running half-alive — channels and agency up while clients silently reached whatever process owned the port (a split-brain with two live agents). Agency candidate attempt budget and parking: evaluation now has memory of prior decisions. A candidate is not re-decided inside a cooldown window (stops per-cycle audit bloat — production had accreted 23,015 decisions for one junk candidate and 1,226 per stuck scheduler candidate), and one that has burned its executed-attempt budget without resolution is PARKED with a single operator notification instead of being re-investigated every cadence tick forever. Config: `decision_cooldown_minutes`, `max_candidate_attempts`, `attempt_window_hours`, `park_retry_after_hours` (zero disables). A new hygiene repair class heals the accumulated churn damage on every install: duplicate `tool-fact:` working-memory accretions collapse, junk unresolved-questions whose candidate exhausted its budget are removed, and aged agency audit rows are pruned (parked markers survive). The semantic response cache is removed entirely: the pipeline cache stage, the llm-layer two-tier cache, the `semantic_cache` table (migration 065), the maintenance eviction task, and the cached guard preset. Production data showed it was harmful and valueless: zero entries stored since 2026-04-16, `tokens_saved = 0` lifetime, and an entirely pathological replay population (greeting/ack replays, a stale clock reading served 11 times, and the incident's stale-directive-to-a-greeting replay). Behavioral soaks always wiped the cache, so all certified behavior was already cache-off. The `no_cache` request field is accepted and ignored for wire compatibility; cache stats surfaces keep their shape and truthfully report zero. In-flight request deduplication (a concurrency concern) is retained.

Highlights

  • The daemon now FAILS LOUD when its API address cannot bind (or the API server later terminates): previously it logged one error and kept running half-alive — channels and agency up while clients silently reached whatever process owned the port (a split-brain with two live agents).
  • Agency candidate attempt budget and parking: evaluation now has memory of prior decisions. A candidate is not re-decided inside a cooldown window (stops per-cycle audit bloat — production had accreted 23,015 decisions for one junk candidate and 1,226 per stuck scheduler candidate), and one that has burned its executed-attempt budget without resolution is PARKED with a single operator notification instead of being re-investigated every cadence tick forever. Config: `decision_cooldown_minutes`, `max_candidate_attempts`, `attempt_window_hours`, `park_retry_after_hours` (zero disables).
  • A new hygiene repair class heals the accumulated churn damage on every install: duplicate `tool-fact:` working-memory accretions collapse, junk unresolved-questions whose candidate exhausted its budget are removed, and aged agency audit rows are pruned (parked markers survive).
  • `RunHygiene` now also runs on a daily cadence inside the maintenance heartbeat, so all shipped repair classes reach every install automatically — previously hygiene only ran when an operator invoked `mechanic --repair` by hand.
  • The semantic response cache is removed entirely: the pipeline cache stage, the llm-layer two-tier cache, the `semantic_cache` table (migration 065), the maintenance eviction task, and the cached guard preset. Production data showed it was harmful and valueless: zero entries stored since 2026-04-16, `tokens_saved = 0` lifetime, and an entirely pathological replay population (greeting/ack replays, a stale clock reading served 11 times, and the incident's stale-directive-to-a-greeting replay). Behavioral soaks always wiped the cache, so all certified behavior was already cache-off. The `no_cache` request field is accepted and ignored for wire compatibility; cache stats surfaces keep their shape and truthfully report zero. In-flight request deduplication (a concurrency concern) is retained.
FIXThe daemon now FAILS LOUD when its API address cannot bind (or the API server later terminates): previously it logged one error and kept running half-alive — channels and agency up while clients silently reached whatever process owned the port (a split-brain with two live agents).
FEATAgency candidate attempt budget and parking: evaluation now has memory of prior decisions. A candidate is not re-decided inside a cooldown window (stops per-cycle audit bloat — production had accreted 23,015 decisions for one junk candidate and 1,226 per stuck scheduler candidate), and one that has burned its executed-attempt budget without resolution is PARKED with a single operator notification instead of being re-investigated every cadence tick forever. Config: `decision_cooldown_minutes`, `max_candidate_attempts`, `attempt_window_hours`, `park_retry_after_hours` (zero disables).
FEATA new hygiene repair class heals the accumulated churn damage on every install: duplicate `tool-fact:` working-memory accretions collapse, junk unresolved-questions whose candidate exhausted its budget are removed, and aged agency audit rows are pruned (parked markers survive).
FEAT`RunHygiene` now also runs on a daily cadence inside the maintenance heartbeat, so all shipped repair classes reach every install automatically — previously hygiene only ran when an operator invoked `mechanic --repair` by hand.
CHOREThe semantic response cache is removed entirely: the pipeline cache stage, the llm-layer two-tier cache, the `semantic_cache` table (migration 065), the maintenance eviction task, and the cached guard preset. Production data showed it was harmful and valueless: zero entries stored since 2026-04-16, `tokens_saved = 0` lifetime, and an entirely pathological replay population (greeting/ack replays, a stale clock reading served 11 times, and the incident's stale-directive-to-a-greeting replay). Behavioral soaks always wiped the cache, so all certified behavior was already cache-off. The `no_cache` request field is accepted and ignored for wire compatibility; cache stats surfaces keep their shape and truthfully report zero. In-flight request deduplication (a concurrency concern) is retained.

v1.1.0

Bug Fixes & Stability & More2026-06-11

Added: 5 changes. Changed: 7 changes. Fixed: 19 changes. Removed: 3 changes. Key changes: Agency/autonomy: runtime-owned policy and execution seams, discrete control levels with conservative defaults, a daily cloud-token budget cap for unattended proactive work, agency audit records, and a forgive-only grounding judge that reduces guard over-firing without weakening hard-safety guards. On-demand tool surface: a small always-native floor plus an embedder-ranked catalog hydrated via a `request_tools` meta-tool (removes context-budget pressure that previously squeezed out memory). Collapsed the two memory tools into a single polymorphic `recall_memory(memory_id?, query?)` verb: an id fetches full content, a topic returns a ranked preview list, and an id-miss with a topic falls back to search. Empty args backfill the query from the last user message. Memory tiering is now fully internal — the source tier no longer appears in the tool schema, the tool output, or the injected memory index. Recall facts reach the verifier via a machine-only `Result.Metadata` envelope, keeping the model-facing output de-tiered and legible. Embedder foundation: `nomic-embed-text` is embedded with its required task-instruction prefixes (in-distribution, stable margins); the ollama runtime is pinned and asserted (`models embedder-check` + startup fail loud on drift); stored vectors carry an `embedding_version` fingerprint and re-embed themselves on a model/prefix/runtime change.

Highlights

  • Agency/autonomy: runtime-owned policy and execution seams, discrete control levels with conservative defaults, a daily cloud-token budget cap for unattended proactive work, agency audit records, and a forgive-only grounding judge that reduces guard over-firing without weakening hard-safety guards.
  • On-demand tool surface: a small always-native floor plus an embedder-ranked catalog hydrated via a `request_tools` meta-tool (removes context-budget pressure that previously squeezed out memory).
  • Multimodal and channels: cross-platform bundled TTS with an audible voice proof, Carbonyl browser runtime backend, camera/bounded-video proof, mail support, media device inventory/selection, and canonical multimodal message storage.
  • Configured-access introspection so capability claims (calendar, mail, …) come from runtime state, not installed-skill impressions.
  • Centralized CLI design language and benchmark/CLI readability improvements.
  • Collapsed the two memory tools into a single polymorphic `recall_memory(memory_id?, query?)` verb: an id fetches full content, a topic returns a ranked preview list, and an id-miss with a topic falls back to search. Empty args backfill the query from the last user message. Memory tiering is now fully internal — the source tier no longer appears in the tool schema, the tool output, or the injected memory index. Recall facts reach the verifier via a machine-only `Result.Metadata` envelope, keeping the model-facing output de-tiered and legible.
  • Embedder foundation: `nomic-embed-text` is embedded with its required task-instruction prefixes (in-distribution, stable margins); the ollama runtime is pinned and asserted (`models embedder-check` + startup fail loud on drift); stored vectors carry an `embedding_version` fingerprint and re-embed themselves on a model/prefix/runtime change.
  • Internal/API boundary: Roboticus REST APIs are external-integration surfaces only; CLI/TUI/internal flows use direct local services and the dashboard uses the WebSocket control channel instead of API loopback.
FEATAgency/autonomy: runtime-owned policy and execution seams, discrete control levels with conservative defaults, a daily cloud-token budget cap for unattended proactive work, agency audit records, and a forgive-only grounding judge that reduces guard over-firing without weakening hard-safety guards.
FEATOn-demand tool surface: a small always-native floor plus an embedder-ranked catalog hydrated via a `request_tools` meta-tool (removes context-budget pressure that previously squeezed out memory).
FEATMultimodal and channels: cross-platform bundled TTS with an audible voice proof, Carbonyl browser runtime backend, camera/bounded-video proof, mail support, media device inventory/selection, and canonical multimodal message storage.
FEATConfigured-access introspection so capability claims (calendar, mail, …) come from runtime state, not installed-skill impressions.
FEATCentralized CLI design language and benchmark/CLI readability improvements.
CHORECollapsed the two memory tools into a single polymorphic `recall_memory(memory_id?, query?)` verb: an id fetches full content, a topic returns a ranked preview list, and an id-miss with a topic falls back to search. Empty args backfill the query from the last user message. Memory tiering is now fully internal — the source tier no longer appears in the tool schema, the tool output, or the injected memory index. Recall facts reach the verifier via a machine-only `Result.Metadata` envelope, keeping the model-facing output de-tiered and legible.
CHOREEmbedder foundation: `nomic-embed-text` is embedded with its required task-instruction prefixes (in-distribution, stable margins); the ollama runtime is pinned and asserted (`models embedder-check` + startup fail loud on drift); stored vectors carry an `embedding_version` fingerprint and re-embed themselves on a model/prefix/runtime change.
CHOREInternal/API boundary: Roboticus REST APIs are external-integration surfaces only; CLI/TUI/internal flows use direct local services and the dashboard uses the WebSocket control channel instead of API loopback.
CHOREConsolidated database maintenance into `mechanic --repair`, backed by a single `Store.RunMaintenance` (snapshot-safe integrity check, FTS rebuild, stale-data prune, vacuum) plus `Store.RunHygiene` (orphan react-traces, false capability-denial quarantine, inactive derived-row pruning, quarantine retention). When the daemon is running, `mechanic --repair` routes all repair work through the daemon's own connection over the WS control seam (`db.maintenance.run`, online-safe incremental vacuum) instead of opening the live database from a second process — removing a cross-process write path that was itself an FTS-corruption vector.
CHORESemantic turn classifier: five embedding-centroid heads replace the brittle phrase-list turn heuristics, each calibrated and soak-gated against the pinned embedder. A tool-grounded turn proactively forces `tool_choice=required` so a weak model calls the tool instead of narrating; a semantic topic shift breaks live-info (web-read) inheritance beyond the lexical markers; marker-less short imperatives are rescued from the conversational fallthrough; and scheduling-vs-web routing ties resolve semantically (explicit URLs stay web). Lexical signals remain the floor — the classifier only extends coverage.
CHOREAdversarial regression harness: permanent, deterministic gate cases distilled from every live-surfaced behavioral defect (cron memory grounding, execution-truth historical reporting, rerun-as-action, topic-switch routing, turn-collapse, transport leaks), run against an isolated clone of a hydrated instance with seeded scheduler and stale-memory fixtures.
CHOREConfig hot-reload: the daemon watches `roboticus.toml`, validates, and applies changes across registered component reloaders with batch rollback on failure, emitting config lifecycle events to the dashboard. Reloads load with boot-path parity (provider-pack + bundled merges) so merge-supplied behavior flags survive a reload; log level is the first hot-applied setting.
FIXEmbedder runtime drift no longer silently degrades behavioral guards (an ollama 0.24→0.30 auto-update had shifted `nomic-embed-text` output past a calibrated guard floor); resolved by the embedder foundation above plus recalibrating the divergence floor against the pinned, prefixed baseline.
FIXGrounding-loop tool-call turns no longer surface as empty responses, and the ReAct loop deadline scales with the model's per-call timeout so slow local models are not killed mid-call.
FIXNormal-surface web evidence delivery: continuation/tool-surface defects, transport-header evidence leaks, and source-URL mis-attribution.
FIXProvider contract/metadata truth and context-capacity error attribution.
FIXWindows stale-updater repair messaging; installer workspace layout initialization; terminal failure presentation (plain voice, no canned jargon).
FIXRecurring `memory_fts` "corruption" is auto-healed: real fts5 corruption now rebuilds the index from the authoritative memory tables (instead of dead-ending at `needs_manual_action`), while the heartbeat's snapshot-confirmed health gate ignores the transient live-FTS/WAL read races that produced the false positives.
FIXCron observability/truth: `/status` reports cron executions (`ran/24h`) so a dead scheduler is no longer hidden behind a vacuous "0 failed/24h"; the agent's cron inventory now carries real per-job execution status (`last_run`/ `last_status`/`next_run`) and the agent is steered to report it rather than claim jobs are "functioning as designed" without evidence; inert `action:"noop"` cron jobs are rejected at the creation boundary.
FIXConversational turn-collapse ("Yes, please do" answered with a stale greeting): both response-cache tiers now bypass context-dependent conversational turns (acknowledgements, affirmations, continuations, short follow-ups) for lookup and store, so a cached reply can never displace an answer that depends on the prior turn.
FIXStale durable memory no longer overrides live tool evidence: volatile tool-event outputs (one-time mutations, failures, transport noise) are kept out of durable memory at formation; recalled context carries an explicit live-evidence-precedence caveat; and `mechanic --repair` quarantines pre-existing volatile rows including promoted ones, reaping every derived projection (memory index, FTS, and the embeddings vector index) so quarantined content cannot resurface through search.
FIXTool-grounded turns on local models: local OpenAI-compatible servers (ollama, vllm, sglang, llama-cpp, docker-model-runner) don't honor `tool_choice=required`; the bundled provider defaults now declare it so the request degrades to `auto` instead of the service hard-failing every local tool turn into a "no tool-capable model" message. A model that *accepts* `required` and ignores it is still distrusted and failed loud.
FIX`execution_truth` no longer rejects honest third-person/historical status reporting; short imperatives ("rerun the daily briefing now") route as actions rather than small talk; an explicit topic change no longer inherits the prior turn's web-research tool routing.
FIXWeb-evidence summaries can no longer surface raw HTTP response headers: leading header blocks are stripped positionally (redirect-chain aware), with standard single-token header names (`Allow`, `Link`, …) filtered as defense-in-depth.
FIXWallet liveness: a failed transaction build or broadcast now rolls back the optimistically allocated nonce, so one transient RPC failure can no longer wedge every subsequent transaction behind a phantom nonce gap until restart.
FIXSession deletion is transactional: the cascade across turns, tool calls, traces, and messages commits atomically and surfaces errors instead of silently orphaning child rows under a deleted session.
FIXBrittle-phrase sweep (operator-mandated, freeze-break): substring/keyword heuristics on the behavioral path were replaced with semantic classification or turn-local evidence grounding, after an empirical probe of each candidate (sites that probed healthy were left untouched). Confirmed and fixed: the keyword intent classifier mis-gating product questions ("what model of laptop should I buy") into model-identity rewrites — superseded by an embedding intent classifier with contrastive exemplars; the scheduler-identifier guard arming off session-wide "cron"/"schedule" markers and rejecting a later unrelated vault answer — now armed only by turn-local scheduler evidence; the placeholder guard retrying explicitly requested fill-in templates to exhaustion — exempted when the prompt asks for a template/skeleton/blank form; under-specified-cron refusal of fully specified purpose-clause jobs ("…to summarize overnight alerts"); and sarcasm coaching firing on sincere one-word praise after successful replies — now grounded in a prior reply that actually invites it.
FIXTool-surface routing no longer strands a turn without the tool it is required to use: the fuzzy embedding scheduling-lean yields to explicit filesystem obligations (it had preempted artifact-write and inspection routing, pruning `write_file`/`read_file` off the surface so the loop rejected the model's correct calls); artifact-write turns pin their write tool by operation class and carry the write requirement regardless of classified intent; short inspection continuations keep a tool surface instead of collapsing to the lightweight envelope; and a verifier coverage failure on a filesystem-inspection turn now delivers the gathered evidence instead of asking the user to restate.
FIXA reply-only output contract ("answer with only READY") no longer deadlocks against the low-value-placeholder guard: the user's explicit contract outranks the placeholder heuristic, so the demanded literal is delivered instead of exhausting every attempt.
FIXEmbedder runtime re-pinned to ollama 0.30.7 after a host auto-update tripped the release pin gate; every calibrated guard floor was re-verified against 0.30.7 (intent, turn-classifier, pending-action divergence, financial gates) before the pin moved.
FIXThe behavior-soak log monitor's orphaned-tool_calls pattern requires adjacency, so healthy model prose mentioning "orphaned tasks" on a line that also carries the `tool_calls=` log field is no longer flagged as a release-gate finding.
CHORERetired the `search_memories` tool; all topic recall now flows through `recall_memory(query)`.
CHORERetired the `mechanic defrag` subcommand: its database maintenance is folded into `mechanic --repair`, and its code-quality scanner moved to a dev/CI tool (`go run ./scripts/codescan`).
CHORERemoved the canned scenario-fingerprint response stages (`continuity_direct`, `source_backed_artifact_direct`) and the hardcoded artifact template: canned prose was answering real conversational turns and letting behavioral soaks pass against fixtures instead of the model. Those turns now run through real inference, and the tool-surface gaps the canned paths had been masking were fixed (see Fixed) rather than re-papered.

v1.0.12

Bug Fixes & Stability2026-05-08

Fixed: 3 changes. Key changes: Hardened `roboticus upgrade all` against transient GitHub release-asset CDN failures by retrying temporary HTTP failures and falling back from `browser_download_url` to the GitHub release asset API URL with `Accept: application/octet-stream`. Added retry/backoff to the public Linux/macOS and Windows bootstrap installers so fresh installs do not fail on a single transient `SHA256SUMS.txt` or binary download error.

Highlights

  • Hardened `roboticus upgrade all` against transient GitHub release-asset CDN failures by retrying temporary HTTP failures and falling back from `browser_download_url` to the GitHub release asset API URL with `Accept: application/octet-stream`.
  • Added retry/backoff to the public Linux/macOS and Windows bootstrap installers so fresh installs do not fail on a single transient `SHA256SUMS.txt` or binary download error.
  • Added install/update regression coverage for transient asset recovery across `upgrade all`, `install.sh`, and `install.ps1`.
FIXHardened `roboticus upgrade all` against transient GitHub release-asset CDN failures by retrying temporary HTTP failures and falling back from `browser_download_url` to the GitHub release asset API URL with `Accept: application/octet-stream`.
FIXAdded retry/backoff to the public Linux/macOS and Windows bootstrap installers so fresh installs do not fail on a single transient `SHA256SUMS.txt` or binary download error.
FIXAdded install/update regression coverage for transient asset recovery across `upgrade all`, `install.sh`, and `install.ps1`.

v1.0.11

Bug Fixes & Stability2026-05-07

Fixed: 8 changes. Key changes: Closed the web/chat streaming liveness gap where a turn could be marked successful without durable, visible assistant content. Made stream finalization pipeline-owned and fail-closed: empty/unusable streams now emit typed visible errors instead of persisting blank assistant messages.

Highlights

  • Closed the web/chat streaming liveness gap where a turn could be marked successful without durable, visible assistant content.
  • Made stream finalization pipeline-owned and fail-closed: empty/unusable streams now emit typed visible errors instead of persisting blank assistant messages.
  • Preserved pre-chunk streaming provider errors so credit/quota failures still trip the provider credit breaker before falling back.
  • Prevented macOS service-install tests from contaminating the operator's real LaunchAgent by refusing Go test binaries and explicit missing config paths at the daemon install seam.
  • Extended the local-state isolation rule from databases to service-manager artifacts such as LaunchAgents, pid files, and operator launch logs.
  • Routed repairable maintenance `quick_check` failures through the central DB-owned derived-structure repair seam before failing heartbeat tasks, while preserving fail-closed behavior for authoritative or unknown corruption.
  • Raised the CI/release Go toolchain to `1.26.3` so security scans run on the standard-library fixes required by `govulncheck`.
  • Synchronized daemon startup worker registration with shutdown waiting so `Start`/`Stop` remains race-detector clean on macOS service lifecycle tests.
FIXClosed the web/chat streaming liveness gap where a turn could be marked successful without durable, visible assistant content.
FIXMade stream finalization pipeline-owned and fail-closed: empty/unusable streams now emit typed visible errors instead of persisting blank assistant messages.
FIXPreserved pre-chunk streaming provider errors so credit/quota failures still trip the provider credit breaker before falling back.
FIXPrevented macOS service-install tests from contaminating the operator's real LaunchAgent by refusing Go test binaries and explicit missing config paths at the daemon install seam.
FIXExtended the local-state isolation rule from databases to service-manager artifacts such as LaunchAgents, pid files, and operator launch logs.
FIXRouted repairable maintenance `quick_check` failures through the central DB-owned derived-structure repair seam before failing heartbeat tasks, while preserving fail-closed behavior for authoritative or unknown corruption.
FIXRaised the CI/release Go toolchain to `1.26.3` so security scans run on the standard-library fixes required by `govulncheck`.
FIXSynchronized daemon startup worker registration with shutdown waiting so `Start`/`Stop` remains race-detector clean on macOS service lifecycle tests.

v1.0.10

Bug Fixes & Stability2026-05-07

Fixed: 6 changes. Key changes: Moved macOS local daemon install/start onto the user LaunchAgent path (`~/Library/LaunchAgents`, `gui/$UID`) instead of defaulting local desktop installs through root LaunchDaemons. Isolated behavior soaks from the operator's live `~/.roboticus/state.db` by default and removed report assumptions tied to live DB snapshotting.

Highlights

  • Moved macOS local daemon install/start onto the user LaunchAgent path (`~/Library/LaunchAgents`, `gui/$UID`) instead of defaulting local desktop installs through root LaunchDaemons.
  • Isolated behavior soaks from the operator's live `~/.roboticus/state.db` by default and removed report assumptions tied to live DB snapshotting.
  • Added mandatory resource-contention warnings and proceed confirmations to behavior soaks and model benchmarks, with explicit CI/release overrides.
  • Centralized scheduler inventory follow-up projection so observed cron evidence is not lost at finalization or misread as a cron-creation request.
  • Made stale sidecar repair output actionable by naming blocked paths and printing concrete cleanup commands.
  • Hardened provider-key alias normalization, OpenAI-compatible tool-call history repair, final-model route attribution, and repairable semantic-memory derived-index handling.
FIXMoved macOS local daemon install/start onto the user LaunchAgent path (`~/Library/LaunchAgents`, `gui/$UID`) instead of defaulting local desktop installs through root LaunchDaemons.
FIXIsolated behavior soaks from the operator's live `~/.roboticus/state.db` by default and removed report assumptions tied to live DB snapshotting.
FIXAdded mandatory resource-contention warnings and proceed confirmations to behavior soaks and model benchmarks, with explicit CI/release overrides.
FIXCentralized scheduler inventory follow-up projection so observed cron evidence is not lost at finalization or misread as a cron-creation request.
FIXMade stale sidecar repair output actionable by naming blocked paths and printing concrete cleanup commands.
FIXHardened provider-key alias normalization, OpenAI-compatible tool-call history repair, final-model route attribution, and repairable semantic-memory derived-index handling.

v1.0.9

Bug Fixes & Stability2026-05-06

Fixed: 4 changes. Key changes: Published the post-`v1.0.8` behavioral hotfix as `v1.0.9` so installer and upgrade flows can resolve a newer binary artifact instead of remaining on the original `v1.0.8` tag. Hardened the release workflow's changelog validation so release versions are matched literally rather than interpreted as regular expressions.

Highlights

  • Published the post-`v1.0.8` behavioral hotfix as `v1.0.9` so installer and upgrade flows can resolve a newer binary artifact instead of remaining on the original `v1.0.8` tag.
  • Hardened the release workflow's changelog validation so release versions are matched literally rather than interpreted as regular expressions.
  • Added a normative SemVer policy and moved the planned feature slate formerly parked after `v1.0.9` to `v1.1.0`; patch numbers remain reserved for hotfix-class releases.
  • Preserved the final expanded behavior-soak gate evidence for the hotfix: `33/33` scenarios passed with all qualitative scorecard families graded `A`.
FIXPublished the post-`v1.0.8` behavioral hotfix as `v1.0.9` so installer and upgrade flows can resolve a newer binary artifact instead of remaining on the original `v1.0.8` tag.
FIXHardened the release workflow's changelog validation so release versions are matched literally rather than interpreted as regular expressions.
FIXAdded a normative SemVer policy and moved the planned feature slate formerly parked after `v1.0.9` to `v1.1.0`; patch numbers remain reserved for hotfix-class releases.
FIXPreserved the final expanded behavior-soak gate evidence for the hotfix: `33/33` scenarios passed with all qualitative scorecard families graded `A`.

v1.0.8

Improvements2026-05-05

Changed: 3 changes. Fixed: 3 changes. Key changes: Turned `v1.0.8` into a diagnostic-trust release focused on benchmark/RCA. Made `web_search` the canonical built-in public-web discovery surface through. Removed release-critical benchmark CLI loopback through Roboticus `/api/**`. Improved provider/RCA classification for request-shape defects, breaker-open.

Highlights

  • Turned `v1.0.8` into a diagnostic-trust release focused on benchmark/RCA
  • Made `web_search` the canonical built-in public-web discovery surface through
  • Tightened release and upgrade expectations around version truth, deterministic
  • Removed release-critical benchmark CLI loopback through Roboticus `/api/**`
  • Improved provider/RCA classification for request-shape defects, breaker-open
  • Hardened behavior/continuity truth around pending-action follow-ups, false
CHORETurned `v1.0.8` into a diagnostic-trust release focused on benchmark/RCA
CHOREMade `web_search` the canonical built-in public-web discovery surface through
CHORETightened release and upgrade expectations around version truth, deterministic
FIXRemoved release-critical benchmark CLI loopback through Roboticus `/api/**`
FIXImproved provider/RCA classification for request-shape defects, breaker-open
FIXHardened behavior/continuity truth around pending-action follow-ups, false

v1.0.7

Improvements2026-04-24

Changed: 3 changes. Fixed: 3 changes. Key changes: Turned `v1.0.7` into an explicit behavior-hardening release with canonical. Tightened model/routing truth so lifecycle policy, intent-scoped exercise,. Removed several framework-owned false negatives around tool use and authoring. Fixed multiple observability/RCA truth seams so turn diagnostics, trace flow,.

Highlights

  • Turned `v1.0.7` into an explicit behavior-hardening release with canonical
  • Tightened model/routing truth so lifecycle policy, intent-scoped exercise,
  • Hardened the release/deployment control plane by making release procedure
  • Removed several framework-owned false negatives around tool use and authoring
  • Fixed multiple observability/RCA truth seams so turn diagnostics, trace flow,
  • Closed release-branch and post-merge CI defects uncovered during the
CHORETurned `v1.0.7` into an explicit behavior-hardening release with canonical
CHORETightened model/routing truth so lifecycle policy, intent-scoped exercise,
CHOREHardened the release/deployment control plane by making release procedure
FIXRemoved several framework-owned false negatives around tool use and authoring
FIXFixed multiple observability/RCA truth seams so turn diagnostics, trace flow,
FIXClosed release-branch and post-merge CI defects uncovered during the

v1.0.6

Improvements2026-04-21

Changed: 8 changes. Key changes: The scoped parity systems have final dispositions in. The release is not claiming verbatim Rust recreation where Go now has a.

Highlights

  • The scoped parity systems have final dispositions in
  • The release is not claiming verbatim Rust recreation where Go now has a
  • Prompt compression is explicitly deferred for this release on negative
  • M3.3 LIKE-block deletion: telemetry surface (`AggregateRetrievalPaths`) is in place; the actual deletion in `retrieval_tiers.go` waits for production traces to demonstrate dormancy per the documented retirement procedure.
  • External behavioral soak rerun pending: the earlier pass-5 residuals around introspection and filesystem behavior have been addressed in code via an introspection alias, a runtime-owned capability-introspection fast path, explicit `~` refusal in both tool resolution and policy evaluation, and stripping parsed tool-call JSON from assistant content. Release confidence should still be refreshed with another managed clone/fresh soak pass before declaring the behavioral matrix fully closed.
  • Fresh-state soak lane: the managed `fresh` lane now boots from an isolated generated default config rather than a copied operator config, so clean-state validation is finally meaningful. Long-duration fresh-state soak evidence is still an rc validation artifact rather than something pinned in this notes file.
  • Prompt compression failed the corrected paired-soak gate and is not accepted for v1.0.6: the repaired harness now evaluates history-bearing scenarios that actually exercise the current Go compression surface. On that gate, baseline passed `3/3` while compression passed `0/3`; the compressed lane lost history recall and inflated latency to roughly 975s / 1540s / 1520s on the three history-bearing scenarios. Prompt compression should remain disabled for this release.
  • Prompt-compression soak lanes are now isolated more defensibly: the paired harness now gives each lane its own base URL/port, waits for managed-server teardown between lanes, and defaults to a much longer lane timeout. That does not clear prompt compression, but it removes a bad source of false failure from the evidence path.
CHOREThe scoped parity systems have final dispositions in
CHOREThe release is not claiming verbatim Rust recreation where Go now has a
CHOREPrompt compression is explicitly deferred for this release on negative
CHOREM3.3 LIKE-block deletion: telemetry surface (`AggregateRetrievalPaths`) is in place; the actual deletion in `retrieval_tiers.go` waits for production traces to demonstrate dormancy per the documented retirement procedure.
CHOREExternal behavioral soak rerun pending: the earlier pass-5 residuals around introspection and filesystem behavior have been addressed in code via an introspection alias, a runtime-owned capability-introspection fast path, explicit `~` refusal in both tool resolution and policy evaluation, and stripping parsed tool-call JSON from assistant content. Release confidence should still be refreshed with another managed clone/fresh soak pass before declaring the behavioral matrix fully closed.
CHOREFresh-state soak lane: the managed `fresh` lane now boots from an isolated generated default config rather than a copied operator config, so clean-state validation is finally meaningful. Long-duration fresh-state soak evidence is still an rc validation artifact rather than something pinned in this notes file.
CHOREPrompt compression failed the corrected paired-soak gate and is not accepted for v1.0.6: the repaired harness now evaluates history-bearing scenarios that actually exercise the current Go compression surface. On that gate, baseline passed `3/3` while compression passed `0/3`; the compressed lane lost history recall and inflated latency to roughly 975s / 1540s / 1520s on the three history-bearing scenarios. Prompt compression should remain disabled for this release.
CHOREPrompt-compression soak lanes are now isolated more defensibly: the paired harness now gives each lane its own base URL/port, waits for managed-server teardown between lanes, and defaults to a much longer lane timeout. That does not clear prompt compression, but it removes a bad source of false failure from the evidence path.

v1.0.3

WebSocket-First Dashboard & Structural Debt2026-04-12

Replaced all HTTP polling with WebSocket topic subscriptions. Pipeline events push real-time activity to dashboard. Struct-driven settings schema. Plugin/app catalog. 8 workspace/theme bug fixes. 77 files changed.

Highlights

  • WebSocket-first: Zero HTTP polling — all dashboard data pushed via WebSocket topic subscriptions
  • Pipeline events: Agent activity (inference, idle, tool use) shown in real-time on workspace canvas
  • Ticket auth: WS connections authenticated via one-time tickets, API key used exactly once
  • Struct-driven settings: Config schema derived from Go struct via reflect (303 fields)
FEATWebSocket topic subscriptions: Dashboard subscribes to topics (workspace, agent.status, models), server pushes snapshots on subscribe and deltas on change
FEATPipeline → EventBus bridge: DashboardNotifier interface publishes agent_working, stream_start, stream_end, agent_idle events
FEATWS ticket validation: One-time tickets consumed on WebSocket upgrade, API key never sent in subsequent requests
FEATStruct-driven settings schema: GET /api/config/schema returns 303 fields with types, defaults, enums, immutability flags
FEATPlugin/app catalog: Registry fallback with install status, theme catalog with variables/textures/fonts
FIX_catalogThemeVars crash: Variable declared at module scope, reset per render cycle
FIXWorkspace footer pinned: height:100% matching Rust (was calc viewport misfire)
FIXWorkstation layout: Equidistant spacing with 80px dynamic edge clamping at any viewport
FIXparseThemeColors cached: DOM reads eliminated from 60fps render loop, invalidated on theme change
FIXTheme previews: Catalog serializes variables/textures/fonts so previews show actual theme colors

v1.0.2

Parity Sweep & Architecture Gaps2026-04-12

Added: 4 bot commands, 5 CLI commands. Fixed: 3 architecture gaps, FTS coverage. Memory system now auto-indexes at ingestion and searches all 5 tiers via FTS5. Model baselining detects memory recall capability.

Highlights

  • Bot command parity: /model, /models, /breaker, /retry with authority gating
  • FTS5 for all tiers: Procedural and relationship memories now searchable via full-text search
  • Auto-indexing: Memories indexed at ingestion, not just during consolidation backfill
  • IntentMemoryRecall: Router can now escalate memory-heavy queries away from weak models
FEATBot commands: /model (show/set/reset override), /models (list chain), /breaker (status/reset), /retry (replay)
FEATIntentMemoryRecall: New exercise intent class with confabulation penalty scoring
FEATCLI parity: channels health/connect/disconnect, update providers/skills, apps alias
FEAT@bot_name stripping: Telegram group mentions now parsed correctly
FIXFTS5 triggers: Procedural + relationship tiers now indexed for full-text search
FIXTable name normalization: memory_fts and memory_index now use consistent names
FIXAuto-indexing: memory_index entries created at ingestion (was: consolidation only)
FIXGap 2: API routes now set SecurityClaim for audit consistency
FIXGap 3: HMAC trust boundary instructions added to system prompt
FIXBanner version: Startup display now shows actual version from release build

v1.0.1

Memory Recall & Tool Serialization2026-04-12

Fixed: 5 bugs. Added: 3 beyond-parity features. Memory recall was fundamentally broken — 5 compounding issues caused confabulation instead of actual recall. Multi-turn tool use with remote providers was silently broken due to message serialization.

Highlights

  • search_memories tool: New agent tool for topic-based memory search (FTS5 + LIKE fallback)
  • Query-aware memory index: Injected index now surfaces topic-matched entries for the current query
  • Two-stage memory injection: Only working memory + recent activity injected directly (Rust parity)
  • Tool serialization fix: Multi-turn tool use with OpenAI, Kimi K2, and other providers now works
FIXFTS5 episodic retrieval: Union strategy with MATCH clause (was: JOIN without MATCH — old memories invisible)
FIXTwo-stage memory injection: Only working + ambient injected; all other tiers via index (was: full dump causing confabulation)
FIXMemory index noise filter: Tool output entries (bash, errors, introspection) excluded from injected index
FIXConfidence inflation: Default 0.8, incremental +0.1 reinforce (was: binary 1.0 reset making all entries indistinguishable)
FIXOpenAI tool_call_id serialization: Assistant tool-call messages now include explicit `content` field (was: omitted by Go's omitempty)
FEATsearch_memories(query) tool: FTS5 + LIKE fallback search across all 5 memory tiers (beyond Rust parity)
FEATQuery-aware memory index: BuildMemoryIndex surfaces topic-matched entries in first 1/3 of injected index
FEATAnti-confabulation behavioral contract: Explicit rule against fabricating memories in system prompt

v1.0.0

New Features & More2026-04-11

Added: 22 changes. Changed: 14 changes. Fixed: 5 changes. Key changes: Go runtime: Full rewrite from Rust to Go with modernc.org/sqlite (no CGO). ReAct agent loop: 25-turn state machine with idle detection and loop prevention. Prompt ordering: Firmware before personality (matching Rust prompt.rs). Injection defense: 5 markers (Rust set), full content replacement with flagging instead of silent strip.

Highlights

  • Go runtime: Full rewrite from Rust to Go with modernc.org/sqlite (no CGO)
  • ReAct agent loop: 25-turn state machine with idle detection and loop prevention
  • 25-guard output safety pipeline: Behavioral, truthfulness, quality, and protocol guards
  • Semantic classifier: Embedding-based guard scoring with 5 exemplar categories (NARRATED_DELEGATION, CAPABILITY_DENIAL, TASK_DEFERRAL, FALSE_COMPLETION, FINANCIAL_ACTION_CLAIM)
  • 10+ LLM providers: OpenAI, Anthropic, Google Gemini, Ollama, OpenRouter, Moonshot, vLLM, llama-cpp, sglang, docker-model-runner
  • 6-axis metascore routing: Efficacy, Cost, Availability, Locality, Confidence, Speed with ML router
  • 3-tier semantic cache: Exact hash, tool-aware TTL, cosine similarity
  • 5-tier memory system: Working, Episodic, Semantic, Procedural, Relationship with FTS5 + HNSW
FEATGo runtime: Full rewrite from Rust to Go with modernc.org/sqlite (no CGO)
FEATReAct agent loop: 25-turn state machine with idle detection and loop prevention
FEAT25-guard output safety pipeline: Behavioral, truthfulness, quality, and protocol guards
FEATSemantic classifier: Embedding-based guard scoring with 5 exemplar categories (NARRATED_DELEGATION, CAPABILITY_DENIAL, TASK_DEFERRAL, FALSE_COMPLETION, FINANCIAL_ACTION_CLAIM)
FEAT10+ LLM providers: OpenAI, Anthropic, Google Gemini, Ollama, OpenRouter, Moonshot, vLLM, llama-cpp, sglang, docker-model-runner
FEAT6-axis metascore routing: Efficacy, Cost, Availability, Locality, Confidence, Speed with ML router
FEAT3-tier semantic cache: Exact hash, tool-aware TTL, cosine similarity
FEAT5-tier memory system: Working, Episodic, Semantic, Procedural, Relationship with FTS5 + HNSW
FEAT9 channel adapters: Telegram, Discord (WebSocket gateway), Signal, WhatsApp, Email (OAuth2), Voice, Matrix (E2E), A2A (X25519+AES), Web (WebSocket)
FEATDiscord WebSocket gateway: Full lifecycle with heartbeat, identify/resume, MESSAGE_CREATE dispatch, reconnection with backoff
FEATEmail OAuth2: XOAUTH2 SASL authentication for Gmail IMAP
FEATMCP client/server: stdio + SSE transports, live-tested with Playwright (21 tools)
FEATRevenue scoring algorithm: 3-component scoring (confidence/effort/risk) with feedback signals
FEATHybrid FTS5+vector search: FTS5 MATCH combined with cosine similarity via weighted merge
FEATEmbedded SPA dashboard: 9,155-line single-page app with routing profile persistence
FEAT38 CLI commands: Full operator surface including models exercise/baseline/reset
FEATEVM wallet: secp256k1, EIP-3009, x402 payments, treasury policy
FEATPlugin system: Managed registry with skill pairing and archive packaging
FEATTUI: bubbletea + lipgloss terminal interface
FEAT4-layer personality: OS, FIRMWARE, OPERATOR, DIRECTIVES (TOML, hot-reloadable)
FEATParity test suite: internal/parity/ package verifying resolved gaps against Rust behavior
FEATRelease footprint document: docs/releases/v1.0.0-footprint.md tracking all 101 gap closures
CHOREPrompt ordering: Firmware before personality (matching Rust prompt.rs)
CHOREInjection defense: 5 markers (Rust set), full content replacement with flagging instead of silent strip
CHOREMoney type: Microdollars replaced with cents (i64, Rust parity), saturating arithmetic
CHOREEmbedding format: JSON text replaced with 4-byte LE IEEE 754 BLOB (Rust parity)
CHOREN-gram hash: Byte trigrams replaced with rune trigrams, removed signed projection
CHOREStop word list: Aligned to Rust's 77-word set (was 63 with wrong mix)
CHOREShell validation: Blanket pattern blocking replaced with Rust's specific compound checks
CHOREGuard behavioral alignment: TaskDeferral (7 tools + semantic), ExecutionTruth (11 intents + FALSE_COMPLETION), InternalJargon (NARRATED_DELEGATION > 0.8), InternalProtocol (3-category, no bracket markers), DeclaredAction (removed Go-unique indicators)
CHOREConsolidation constants: Extracted magic numbers to named constants (DedupJaccardThreshold, DecayFactor, DecayFloor, PromotionGroupThreshold)
CHOREConfig defaults: Treasury limits aligned to Rust (daily_transfer=2000, hourly=500, reserve=5, inference=50)
CHOREA2A rate limit: Zero value means unlimited (was default to 30)
CHOREMatrix timestamp: Server TS replaced with local clock (Rust parity: Utc::now())
CHOREMCP notifications: Fixed JSON-RPC notification ID bug (notifications must not have "id" field)
CHORESkill formatting: Flat list replaced with nested subsections (### Skill N)
FIXRouting profile persistence: 6-axis profile now stored directly as RoutingProfileData, load prefers persisted values over lossy-derived defaults
FIXHNSW index: BuildFromStore reads embedding_blob (binary LE) instead of nonexistent embedding_json column
FIXPost-turn embedding: Writes binary BLOB format instead of JSON text into BLOB column
FIXConsolidation quiescence gate: Data-moving phases skip when session active within 5 seconds
FIXCron pipeline compliance: Cron executor uses RunPipeline (was already correct, verified)

v0.11.0

New Features & More2026-03-25

Added: 5 changes. Changed: 4 changes. Fixed: 4 changes. Key changes: Agent efficacy push: Memory introspection, selective forgetting, relationship-memory automation, and task operating state are now first-class parts of the shared pipeline. Introspection-driven execution: Task-oriented turns now begin from introspected runtime truth, can compose specialists from a clean slate, and preserve executed state across normalization retries. Delegation and composition flow: Empty-roster specialist requests now progress into composition and delegation instead of collapsing into narrated intent or centralization. Task-path truthfulness: Filesystem/runtime blockers now surface as real blockers instead of canned fallback prose.

Highlights

  • Agent efficacy push: Memory introspection, selective forgetting, relationship-memory automation, and task operating state are now first-class parts of the shared pipeline.
  • Introspection-driven execution: Task-oriented turns now begin from introspected runtime truth, can compose specialists from a clean slate, and preserve executed state across normalization retries.
  • MCP release-grade management: Shared `/api/mcp/servers` management surface aligned across dashboard and CLI.
  • Skill and subagent utilization telemetry: Usage count and last-used signals exposed for skills and subagents.
  • Release vetting automation: Added `scripts/run-v0110-vetting.sh` and `docs/testing/v0110-vetting-matrix.md` to lock in the v0.11.0 regression contract.
  • Delegation and composition flow: Empty-roster specialist requests now progress into composition and delegation instead of collapsing into narrated intent or centralization.
  • Task-path truthfulness: Filesystem/runtime blockers now surface as real blockers instead of canned fallback prose.
  • Prompt and planner behavior: Introspection is now treated as the first operational step for task work and feeds a shared task operating state/action planner.
FEATAgent efficacy push: Memory introspection, selective forgetting, relationship-memory automation, and task operating state are now first-class parts of the shared pipeline.
FEATIntrospection-driven execution: Task-oriented turns now begin from introspected runtime truth, can compose specialists from a clean slate, and preserve executed state across normalization retries.
FEATMCP release-grade management: Shared `/api/mcp/servers` management surface aligned across dashboard and CLI.
FEATSkill and subagent utilization telemetry: Usage count and last-used signals exposed for skills and subagents.
FEATRelease vetting automation: Added `scripts/run-v0110-vetting.sh` and `docs/testing/v0110-vetting-matrix.md` to lock in the v0.11.0 regression contract.
CHOREDelegation and composition flow: Empty-roster specialist requests now progress into composition and delegation instead of collapsing into narrated intent or centralization.
CHORETask-path truthfulness: Filesystem/runtime blockers now surface as real blockers instead of canned fallback prose.
CHOREPrompt and planner behavior: Introspection is now treated as the first operational step for task work and feeds a shared task operating state/action planner.
CHORERelease documentation: Active docs, architecture notes, roadmap entries, and release gates now reflect shipped v0.11.0 behavior.
FIXPipeline trace drift: Legacy databases missing `pipeline_traces.session_id` and related fields are repaired on boot.
FIXPrompt Performance persistence: Routing weights and context budget now persist and rehydrate correctly.
FIXDashboard regressions: Repaired session archive, raw TOML editing, Observability nav, semantic memory navigation, roster skill drill-down, workspace symmetry, and related operator-surface gaps.
FIXAnalysis/recommendation soak failures: Live deep-analysis surfaces validated against a stronger provider path during soak.

v0.10.0

Correctness, Safety & Operational Maturity (14 changes)2026-03-23

Added: 8 changes. Fixed: 4 changes. Changed: 2 changes. Key changes: Model categorization with 29-model capability profiles, skill authoring API, Landlock/Job Object script confinement, typestate session lifecycle, delegation scoring engine, and critical signal adapter fixes.

Highlights

  • Model categorization (Phase 1): 10 task categories, 29 model profiles across 8 providers, category-aware routing with `category_fit` metascore dimension.
  • Skill authoring API: Create, validate, and publish Markdown instruction skills via `POST /api/skills/author`.
  • Landlock & Job Object confinement: Linux filesystem sandboxing and Windows process isolation for script execution.
  • Typestate sessions: Compile-time session lifecycle — `Session<Created>` → `Session<Active>` → `Session<Closed>`.
  • Delegation scoring engine: `score_agent_fit()`, `composite_fit_ratio()`, and `utility_margin_for_delegation()` for decomposition decisions.
  • Signal adapter critical fixes: Replaced `std::sync::Mutex` in async context, added rate limiting, bounded buffer growth.
FEATModel categorization (Phase 1): `TaskCategory` enum (10 types), `classify_task()`, benchmark profiles for 29 models, `CategoryQualityTracker`, and `category_fit` metascore dimension (0.15 weight).
FEATSkill authoring API: `POST /api/skills/author` for creating, validating, and publishing Markdown instruction skills with safety scanning.
FEATLandlock confinement: Linux filesystem sandboxing via `landlock` crate for script execution. Windows Job Object isolation.
FEATTypestate session lifecycle: `Session<Created>`, `Session<Active>`, `Session<Closed>` compile-time state machine in `roboticus-db`.
FEATDelegation scoring engine: `score_agent_fit()`, `composite_fit_ratio()`, `utility_margin_for_delegation()` for principled decomposition gate decisions.
FEATOpenAPI spec endpoint: `GET /openapi.json` serves OpenAPI 3.1 spec; `GET /docs` provides spec access for Swagger UI viewers.
FEATCodex CLI plugin: Delegate coding tasks to OpenAI Codex CLI with structured JSON output and approval mode support.
FEATDead letter alerting: Atomic counter with configurable threshold, error-level logging, and `GET /api/stats/delivery` endpoint.
FIXSignal adapter async/sync mutex (Critical): Replaced `std::sync::Mutex<VecDeque>` with bounded `tokio::sync::mpsc` channel to eliminate runtime thread blocking.
FIXSignal adapter rate limiting: Added `governor::RateLimiter` (5 req/s default) to prevent signal-cli daemon DoS.
FIXDelivery queue error detection: `is_permanent_error()` now extracts HTTP status codes first (429=transient, 4xx=permanent, 5xx=transient).
FIXPlugin catalog: Registry manifest now includes `plugins` section; empty catalog shows helpful message instead of hard error.
CHOREFormatter single-pass optimization: Replaced 3-allocation `strip→clean→collapse` chain with single-pass `clean_content()` across all formatters.
CHOREMetascore weight redistribution: Adjusted routing weights to accommodate new `category_fit` dimension (0.15).

v0.9.9

Terminal UX & Release Hardening (8 changes)2026-03-18

Added: 6 changes. Changed: 1 change. Fixed: 1 change. Key changes: New `roboticus tui` terminal application, configurable context budget tiers, integrations management endpoints/CLI, tool output noise filtering, and dashboard configuration/routing UX improvements.

Highlights

  • Terminal UI: Added `roboticus tui` (`roboticus-tui` crate) with chat, logs, status bar, streaming responses, and session resume.
  • Context budget tuning: Added configurable L0-L3 token budgets and per-channel minimum complexity level controls.
  • Integrations management: Added `POST /api/channels/{platform}/test`, dashboard per-channel probes, and `roboticus integrations` CLI commands.
  • Tool output filter chain: Added ANSI/progress/duplicate/whitespace filtering before LLM observation to reduce token noise.
  • Dashboard and routing polish: Exposed unconfigured sections with enable actions and improved routing profile validation/toasts/defaults.
  • Default bind address: Changed defaults from `127.0.0.1` to `localhost` for safer local consistency.
FEATTerminal user interface (`roboticus tui`): New `roboticus-tui` crate with chat/log/status UX, streaming responses, and session create/resume support.
FEATContext budget tuning: Configurable `[context_budget]` tiers with dashboard sliders and per-channel minimum complexity level.
FEATIntegrations management: Added channel probe endpoint (`POST /api/channels/{platform}/test`), dashboard integrations panel controls, and `roboticus integrations` CLI group.
FEATTool output noise filter: Introduced `ToolOutputFilterChain` with ANSI strip, progress-line filtering, duplicate-line dedupe, and whitespace normalization.
FEATDashboard config exposure: Unconfigured sections/channels now render in the dashboard with explicit enable actions.
FEATRouting profile polish: Added >1.0 weight validation warning, apply toast, and default profile display when unset.
CHOREDefault bind address: Switched defaults/docs from `127.0.0.1` to `localhost` (loopback literals retained where RFC-required).
FIXWindows script-runner tests: Added `#[cfg(unix)]` guard around Unix-only permissions test module to prevent Windows compile failures.

v0.9.8

Platform Refactor & Reliability (22 changes)2026-03-16

Added: 7 changes. Fixed: 10 changes. Changed: 5 changes. Key changes: server crate split (`roboticus-cli`/`roboticus-api`/slim server), unified error model, channel adapter helper extraction, model categorization/router spec, and broad hardening around SQL safety, session integrity, config generation, and silent error triage.

Highlights

  • Server crate split: Decomposed the large server crate into `roboticus-cli`, `roboticus-api`, and a slim `roboticus` runtime bootstrap.
  • Error type unification: Consolidated into a nested `RoboticusError` hierarchy with clean `From` conversions.
  • Channel adapter helper extraction: Added shared formatter/chunking/allowlist helpers across channel adapters.
  • Model categorization spec: Added 10-category task taxonomy with routing/orchestrator integration points.
  • SQL safety + session integrity: Hardened `drop_column` identifier handling and fixed session `find_or_create` error swallowing.
  • Config and platform reliability: Fixed Windows TOML path escaping and converted silent failures into explicit logging/warnings.
FEATServer crate split: Split `roboticus-server` into `roboticus-cli`, `roboticus-api`, and slim `roboticus` runtime entrypoint.
FEATError type unification: Introduced nested `RoboticusError` hierarchy with `thiserror` + `From` conversion coverage.
FEATChannel adapter helpers: Added shared `ChannelFormatter::format()`, `chunk_message()`, and allowlist checks.
FEATModel categorization spec: Added 10-category task taxonomy and integration points for routing/orchestrator flows.
FEAT`--json` listing support: Added structured JSON output to all listing-style CLI commands.
FEAT`/health` alias and `/dashboard` redirect: Added convenience endpoint routing for operators.
FEATConfig backup management: Moved backups to `./backups/` with retention by count and age.
FIXSQL injection hardening in `drop_column`: Enforced identifier validation + safe quoting.
FIXSession `find_or_create`: Stopped swallowing real DB failures by removing `.ok()`-based fallback behavior.
FIXKeystore refresh observability: Converted silent refresh failures into explicit `tracing::warn` logs.
FIXWindows TOML path escaping: Added path normalization for generated config values on Windows.
FIXSilent error triage: Implemented explicit logging/warning tiers for previously silent failure paths.
CHOREDependency cleanup: Removed 19 unused dependencies left over from crate split transitions.
CHORE`Wallet::test_mock()` feature gate: Restricted to `test-support` feature and excluded from production artifacts.
CHOREDead code and duplicate test utilities cleanup: Consolidated shared helpers and removed stale paths.

v0.9.7

Bug Fixes & Stability (26 changes)2026-03-14

Added: 8 changes. Fixed: 18 changes. Key changes: DB fitness hardening (DF-1–DF-18): 18-item SQLite performance audit resolved — retention pruning for 5 high-growth tables, orphan cleanup sweeps (working memory + embeddings), `auto_vacuum=INCREMENTAL`, 6 missing indexes, episodic dead-entry pruning, cache NULL-expiry fix, `PRAGMA synchronous=NORMAL` under WAL, CHECK constraints on 11 columns, and dead `proxy_stats` table removal. Memory hygiene mechanic: `roboticus mechanic` detects and (with `--repair`) purges contaminated memory entries using 7 deterministic LIKE-prefix patterns across 3 tiers, with JSON-structured findings. Circuit breaker window reset: `record_failure()` now tracks `window_start` for rolling-window accumulation — failures spaced ~60s apart correctly accumulate instead of resetting. Embedding auth for local providers: `EmbeddingConfig.is_local` skips API key resolution and auth headers for Ollama/llama.cpp.

Highlights

  • DB fitness hardening (DF-1–DF-18): 18-item SQLite performance audit resolved — retention pruning for 5 high-growth tables, orphan cleanup sweeps (working memory + embeddings), `auto_vacuum=INCREMENTAL`, 6 missing indexes, episodic dead-entry pruning, cache NULL-expiry fix, `PRAGMA synchronous=NORMAL` under WAL, CHECK constraints on 11 columns, and dead `proxy_stats` table removal.
  • Memory hygiene mechanic: `roboticus mechanic` detects and (with `--repair`) purges contaminated memory entries using 7 deterministic LIKE-prefix patterns across 3 tiers, with JSON-structured findings.
  • Sandbox boundary management: Filesystem confinement for skill scripts (skills_dir + `$ROBOTICUS_WORKSPACE`, no traversal/symlink escape), configurable network isolation (`unshare(CLONE_NEWNET)` on Linux), memory ceiling via `RLIMIT_AS`, interpreter allowlist via absolute-path resolution, and mechanic sandbox health reporting.
  • Filesystem security overhaul: `FilesystemSecurityConfig` with `workspace_only` mode, ~25 default protected path patterns, `tool_allowed_paths` whitelist (auto-populated from Obsidian vault path), macOS `sandbox-exec` write-denial confinement, and dashboard UI toggles.
  • Unified pipeline architecture: `IntentRegistry` (22-variant `Intent` enum), `GuardChain` (12 guards with `full()`/`cached()`/`streaming()` presets), `ShortcutDispatcher` (15 handlers replacing 983-line god function), `PipelineConfig` (4 presets: `api`/`streaming`/`channel`/`cron`), and `DedupGuard` RAII replacing 11 manual release patterns. Net ~653 lines removed.
  • ChannelFormatter trait: Per-platform output formatting with static dispatch registry — `TelegramFormatter` (Markdown→MarkdownV2), `DiscordFormatter`, `WhatsAppFormatter`, `SignalFormatter`, `WebFormatter`, `EmailFormatter` — wired into `channel_message.rs` delivery path. 31 unit tests.
  • Configurable inference timeouts: Per-provider `timeout_seconds` setting (`[providers.*.timeout_seconds]`) with 300-second default, surfaced in dashboard provider configuration.
  • Dashboard session ID copy button: One-click copy-to-clipboard for session IDs in the Sessions panel.
FEATDB fitness hardening (DF-1–DF-18): 18-item SQLite performance audit resolved — retention pruning for 5 high-growth tables, orphan cleanup sweeps (working memory + embeddings), `auto_vacuum=INCREMENTAL`, 6 missing indexes, episodic dead-entry pruning, cache NULL-expiry fix, `PRAGMA synchronous=NORMAL` under WAL, CHECK constraints on 11 columns, and dead `proxy_stats` table removal.
FEATMemory hygiene mechanic: `roboticus mechanic` detects and (with `--repair`) purges contaminated memory entries using 7 deterministic LIKE-prefix patterns across 3 tiers, with JSON-structured findings.
FEATSandbox boundary management: Filesystem confinement for skill scripts (skills_dir + `$ROBOTICUS_WORKSPACE`, no traversal/symlink escape), configurable network isolation (`unshare(CLONE_NEWNET)` on Linux), memory ceiling via `RLIMIT_AS`, interpreter allowlist via absolute-path resolution, and mechanic sandbox health reporting.
FEATFilesystem security overhaul: `FilesystemSecurityConfig` with `workspace_only` mode, ~25 default protected path patterns, `tool_allowed_paths` whitelist (auto-populated from Obsidian vault path), macOS `sandbox-exec` write-denial confinement, and dashboard UI toggles.
FEATUnified pipeline architecture: `IntentRegistry` (22-variant `Intent` enum), `GuardChain` (12 guards with `full()`/`cached()`/`streaming()` presets), `ShortcutDispatcher` (15 handlers replacing 983-line god function), `PipelineConfig` (4 presets: `api`/`streaming`/`channel`/`cron`), and `DedupGuard` RAII replacing 11 manual release patterns. Net ~653 lines removed.
FEATChannelFormatter trait: Per-platform output formatting with static dispatch registry — `TelegramFormatter` (Markdown→MarkdownV2), `DiscordFormatter`, `WhatsAppFormatter`, `SignalFormatter`, `WebFormatter`, `EmailFormatter` — wired into `channel_message.rs` delivery path. 31 unit tests.
FEATConfigurable inference timeouts: Per-provider `timeout_seconds` setting (`[providers.*.timeout_seconds]`) with 300-second default, surfaced in dashboard provider configuration.
FEATDashboard session ID copy button: One-click copy-to-clipboard for session IDs in the Sessions panel.
FIXCircuit breaker window reset: `record_failure()` now tracks `window_start` for rolling-window accumulation — failures spaced ~60s apart correctly accumulate instead of resetting.
FIXEmbedding auth for local providers: `EmbeddingConfig.is_local` skips API key resolution and auth headers for Ollama/llama.cpp.
FIXCron `schedule_kind: "once"` support: Runtime maps "once" → "at" dispatch, calls `DurableScheduler::evaluate_at()`, auto-disables after single execution.
FIXVault path whitelisting: `tool_allowed_paths` auto-populated from `obsidian.vault_path` during config normalization — workspace-only mode no longer blocks configured external paths.
FIXFleet activity chart capacity model: Stacked area normalizes per-agent scores by `1/agentCount` with `fixedMax: 1.0`.
FIXCache guard parity: `cached()` guard set now includes `SubagentClaim` + `LiteraryQuoteRetry` (previously missing).
FIXExecutionTruthGuard: Tool-results bypass bug removed.
FIXCollapsible if lint: Updated `impl_core.rs` to use `if let` chain (edition 2024).
FIXWallet RPC rate-limit backoff: `get_all_balances()` detects rate-limit error codes (`-32016`, `-32005`, `429`) and stops iterating remaining tokens instead of repeatedly hitting the provider.
FIXCron once-type orphan jobs: Jobs with `schedule_kind: "once"` and no `schedule_expr` are now auto-disabled on first encounter instead of emitting a warning every 60s.
FIXDashboard sidebar footer: Navigation bar footer now stays pinned to the bottom of the viewport (added `height: 100%` to sidebar container).
FIXDashboard custom model Add button: Custom model text input row now has its own Add button; both Add buttons use a shared class selector.
FIXTelegram double-underscore italic: `text` was incorrectly emitted as Telegram underline instead of italic — formatter now maps to `_text_`.
FIXConfig hot-reload path divergence: `normalize_paths()` and `merge_bundled_providers()` were skipped during hot-reload — reloaded configs now match boot-time normalization.
FIXRouting audit fixes: Attempt counter not incrementing on retry, `u32` truncation on cost metrics, misleading timeout error message wording.
FIXDashboard UI stall during inference: 4 `RwLock` guard-scope fixes release locks before async I/O, preventing cascading reader starvation.
FIXCron semaphore hot-reload race: Semaphore not released when cron runtime reloads config, causing phantom permit exhaustion. Dead `LlmService` method removed, lock consolidation in admin routes.
FIXAgent audit fixes: Tautological always-true test condition, timeout hint parsing edge case, unreachable branch removal.

v0.9.6

New Features (14 changes)2026-03-12

Added: 14 changes. Key changes: Compliance-first self-funding control plane: Complete revenue opportunity lifecycle (intake → qualify → score → plan → fulfill → settle) with DB-backed restart safety, strategy-level scoring (confidence/effort/risk/priority/recommendation), feedback persistence per opportunity and summary by strategy, configurable post-settlement asset routing (default `USDC`), EVM swap submission with tx-hash tracking and on-chain receipt reconciliation, tax payout lifecycle mirroring swap tasks, and operator-visible accounting (net profit, attributable costs, retained earnings, tax allocation) across API, CLI, and mechanic surfaces. Revenue mechanic integration: Mechanic can probe, reconcile, and repair orphaned or stale revenue jobs and swap/tax reconciliation mismatches via `run_gateway_provider_and_revenue_checks` and `run_gateway_integrated_repair_sweep`.

Highlights

  • Compliance-first self-funding control plane: Complete revenue opportunity lifecycle (intake → qualify → score → plan → fulfill → settle) with DB-backed restart safety, strategy-level scoring (confidence/effort/risk/priority/recommendation), feedback persistence per opportunity and summary by strategy, configurable post-settlement asset routing (default `USDC`), EVM swap submission with tx-hash tracking and on-chain receipt reconciliation, tax payout lifecycle mirroring swap tasks, and operator-visible accounting (net profit, attributable costs, retained earnings, tax allocation) across API, CLI, and mechanic surfaces.
  • Revenue mechanic integration: Mechanic can probe, reconcile, and repair orphaned or stale revenue jobs and swap/tax reconciliation mismatches via `run_gateway_provider_and_revenue_checks` and `run_gateway_integrated_repair_sweep`.
  • Skills catalog: `PluginCatalog` with CLI flows (`roboticus skills catalog list/install/activate`) and API endpoints (`GET/POST /api/skills/catalog`, `/install`, `/activate`). Registry manifest fetch from remote URL.
  • Skill registry protocol: Migration 022 adds `version`, `author`, `registry_source` columns to skills table. Multi-registry support via `RegistrySource { name, url, priority, enabled }` with backward-compatible fallback from legacy single-URL `registry_url`.
  • Multi-registry fetch: Registry sync iterates all configured sources, namespaces skills as `{registry_name}/{skill_name}` for non-local sources, applies semver comparison to skip redundant downloads, and resolves conflicts by registry priority.
  • Learning loop closure: Agent now detects repeating multi-step tool sequences on session close and synthesizes reusable SKILL.md procedure files. `learned_skills` table (migration 021) tracks reinforcement history (success/failure counts, priority). `LearningConfig` exposes tuneable thresholds for minimum sequence length, success ratio, priority boost/decay, and skill cap. Inspired by recent work on autonomous tool-use learning in LLM agents ([arXiv:2603.05344](https://arxiv.org/abs/2603.05344)).
  • Procedural failure recording: `record_procedural_failure()` (previously dead code in the DB layer) is now called from `ingest_turn()` when tool results indicate failure, closing the procedural memory feedback loop.
  • Skill priority adjustment: Governor `tick()` now runs `adjust_learned_skill_priorities()` after episodic decay — learned skills with high success ratios get priority boosts; those with poor ratios get decayed.
FEATCompliance-first self-funding control plane: Complete revenue opportunity lifecycle (intake → qualify → score → plan → fulfill → settle) with DB-backed restart safety, strategy-level scoring (confidence/effort/risk/priority/recommendation), feedback persistence per opportunity and summary by strategy, configurable post-settlement asset routing (default `USDC`), EVM swap submission with tx-hash tracking and on-chain receipt reconciliation, tax payout lifecycle mirroring swap tasks, and operator-visible accounting (net profit, attributable costs, retained earnings, tax allocation) across API, CLI, and mechanic surfaces.
FEATRevenue mechanic integration: Mechanic can probe, reconcile, and repair orphaned or stale revenue jobs and swap/tax reconciliation mismatches via `run_gateway_provider_and_revenue_checks` and `run_gateway_integrated_repair_sweep`.
FEATSkills catalog: `PluginCatalog` with CLI flows (`roboticus skills catalog list/install/activate`) and API endpoints (`GET/POST /api/skills/catalog`, `/install`, `/activate`). Registry manifest fetch from remote URL.
FEATSkill registry protocol: Migration 022 adds `version`, `author`, `registry_source` columns to skills table. Multi-registry support via `RegistrySource { name, url, priority, enabled }` with backward-compatible fallback from legacy single-URL `registry_url`.
FEATMulti-registry fetch: Registry sync iterates all configured sources, namespaces skills as `{registry_name}/{skill_name}` for non-local sources, applies semver comparison to skip redundant downloads, and resolves conflicts by registry priority.
FEATLearning loop closure: Agent now detects repeating multi-step tool sequences on session close and synthesizes reusable SKILL.md procedure files. `learned_skills` table (migration 021) tracks reinforcement history (success/failure counts, priority). `LearningConfig` exposes tuneable thresholds for minimum sequence length, success ratio, priority boost/decay, and skill cap. Inspired by recent work on autonomous tool-use learning in LLM agents ([arXiv:2603.05344](https://arxiv.org/abs/2603.05344)).
FEATProcedural failure recording: `record_procedural_failure()` (previously dead code in the DB layer) is now called from `ingest_turn()` when tool results indicate failure, closing the procedural memory feedback loop.
FEATSkill priority adjustment: Governor `tick()` now runs `adjust_learned_skill_priorities()` after episodic decay — learned skills with high success ratios get priority boosts; those with poor ratios get decayed.
FEATSkill subdirectory loading: `SkillLoader` now recurses into `learned/` subdirectory, loading machine-synthesized skills alongside hand-authored ones.
FEATProgressive context compaction: 5-stage compaction (`Trim` → `Summarize` → `Archive` → `Evict` → `Emergency`) in `compact_before_archive()` with `CompactionStage::from_excess()` selector.
FEATDecay-weighted episodic retrieval: `rerank_episodic_by_decay()` applies time-based decay at retrieval time, preventing stale context from dominating memory budget.
FEATInstruction anti-fade micro-reminders: Event-driven system prompt reinforcement at agent decision points to combat instruction-following drift.
FEATx402 autonomous payment: LLM HTTP client now handles `402 Payment Required` responses with autonomous on-chain payment and request retry.
FEATHomebrew & Winget packaging: `release.yml` contains complete `update-homebrew` (SHA256 extraction, formula generation, tap push) and `update-winget` (`vedantmgoyal9/winget-releaser@v2`) jobs. Activation requires tap repo creation and secrets provisioning.

v0.9.5

Improvements & More2026-03-06

Changed: 8 changes. Fixed: 5 changes. Note: 1 change. Key changes: Terminology normalization: `soul_text` → `os_text`, `soul_history` → `os_personality_history` (migration 020) for firmware/OS terminology coherency. Behavior soak hardening: `scripts/run-agent-behavior-soak.py` now includes regression checks for filesystem capability truthfulness, subagent capability response quality, and affirmative continuation quality, with rubric updates to score substantive outcomes over brittle phrase matching. Internal protocol fallback leakage: response sanitization no longer surfaces protocol-placeholder fallback text; empty/degraded sanitized content now resolves through deterministic user-facing quality fallback. Markdown count execution reliability: execution shortcut path now handles recursive markdown-file count prompts deterministically, including strict numeric-only responses when requested (`count only` / `only the number` style prompts).

Highlights

  • Terminology normalization: `soul_text` → `os_text`, `soul_history` → `os_personality_history` (migration 020) for firmware/OS terminology coherency.
  • Behavior soak hardening: `scripts/run-agent-behavior-soak.py` now includes regression checks for filesystem capability truthfulness, subagent capability response quality, and affirmative continuation quality, with rubric updates to score substantive outcomes over brittle phrase matching.
  • Roadmap/release traceability: `docs/releases/v0.9.5.md` and `docs/ROADMAP.md` updated with current v0.9.5 prep status for speculative execution, browser runtime support, CLI skill roadmap slice, and behavior continuity validation.
  • Architecture documentation: Added explicit v0.9.5-prep control/dataflow coverage for deterministic execution shortcuts and guarded response sanitization in `docs/architecture/roboticus-dataflow.md` and `docs/architecture/roboticus-sequences.md`.
  • Browser runtime continuity: Browser action execution now attempts a single stop/start session recovery when CDP disconnect/closed-socket errors are detected, limited to idempotent actions to avoid duplicate side effects on replay.
  • Autonomy turn-budget controls: Added configurable agent-level ReAct budget controls (`autonomy_max_react_turns`, `autonomy_max_turn_duration_seconds`) and wired enforcement into the runtime loop.
  • CLI adapter response contract: `run_script` now emits stable typed metadata (`adapter`, `schema_version`, `status`, `error_class`) and normalized script error classes for downstream handling.
  • Speculative policy invariants: Added explicit test coverage enforcing Safe-only speculative eligibility (Caution/Dangerous/Forbidden remain excluded from speculative execution).
CHORETerminology normalization: `soul_text` → `os_text`, `soul_history` → `os_personality_history` (migration 020) for firmware/OS terminology coherency.
CHOREBehavior soak hardening: `scripts/run-agent-behavior-soak.py` now includes regression checks for filesystem capability truthfulness, subagent capability response quality, and affirmative continuation quality, with rubric updates to score substantive outcomes over brittle phrase matching.
CHORERoadmap/release traceability: `docs/releases/v0.9.5.md` and `docs/ROADMAP.md` updated with current v0.9.5 prep status for speculative execution, browser runtime support, CLI skill roadmap slice, and behavior continuity validation.
CHOREArchitecture documentation: Added explicit v0.9.5-prep control/dataflow coverage for deterministic execution shortcuts and guarded response sanitization in `docs/architecture/roboticus-dataflow.md` and `docs/architecture/roboticus-sequences.md`.
CHOREBrowser runtime continuity: Browser action execution now attempts a single stop/start session recovery when CDP disconnect/closed-socket errors are detected, limited to idempotent actions to avoid duplicate side effects on replay.
CHOREAutonomy turn-budget controls: Added configurable agent-level ReAct budget controls (`autonomy_max_react_turns`, `autonomy_max_turn_duration_seconds`) and wired enforcement into the runtime loop.
CHORECLI adapter response contract: `run_script` now emits stable typed metadata (`adapter`, `schema_version`, `status`, `error_class`) and normalized script error classes for downstream handling.
CHORESpeculative policy invariants: Added explicit test coverage enforcing Safe-only speculative eligibility (Caution/Dangerous/Forbidden remain excluded from speculative execution).
FIXInternal protocol fallback leakage: response sanitization no longer surfaces protocol-placeholder fallback text; empty/degraded sanitized content now resolves through deterministic user-facing quality fallback.
FIXMarkdown count execution reliability: execution shortcut path now handles recursive markdown-file count prompts deterministically, including strict numeric-only responses when requested (`count only` / `only the number` style prompts).
FIXDelegation shortcut boundary: markdown-count shortcut no longer hijacks explicitly delegated prompts, preserving delegation intent handling.
FIXSpeculative branch cleanup safety: introduced RAII speculation slot guards and abort-path tests to guarantee no slot leakage when speculative tasks are canceled.
FIXCLI skill sandbox isolation coverage: added explicit tests that secret env vars are stripped while only allowlisted runtime vars are propagated under `skills.sandbox_env=true`.
CHORE$50 seed exercise deferred: The revenue infrastructure is proven via integration tests and the seed exercise plan is authored (`docs/releases/v0.9.6-seed-exercise.md`), but the exercise itself is deferred — the economic ecosystem for autonomous bot services is still nascent. The rails are in place; the market is not.

v0.9.4+hotfix.1

Improvements & More2026-03-05

Added: 3 changes. Changed: 7 changes. Fixed: 2 changes. Security: 1 change. Key changes: Routing observability UX: Metrics dashboard now includes an explorable model-decision graph and a routing-profile spider graph (correctness/cost/speed) with runtime apply support via safe config patching. Model shift telemetry: Non-streaming inference pipeline now emits websocket `model_shift` events when execution model differs from selected model (fallback or cache continuity path). Agent message contract: `/api/agent/message` responses now expose both routing-time and execution-time model fields (`selected_model`, `model`, `model_shift_from`) for continuity diagnostics. Routing dataset privacy default: `GET /api/models/routing-dataset` now redacts `user_excerpt` by default; explicit opt-in is required to include excerpts.

Highlights

  • Routing observability UX: Metrics dashboard now includes an explorable model-decision graph and a routing-profile spider graph (correctness/cost/speed) with runtime apply support via safe config patching.
  • Model shift telemetry: Non-streaming inference pipeline now emits websocket `model_shift` events when execution model differs from selected model (fallback or cache continuity path).
  • Routing profile roadmap spec: Added `docs/roadmap/0.9.4/features/user-routing-profile-spider-graph.md` and linked roadmap entry.
  • Agent message contract: `/api/agent/message` responses now expose both routing-time and execution-time model fields (`selected_model`, `model`, `model_shift_from`) for continuity diagnostics.
  • Routing dataset privacy default: `GET /api/models/routing-dataset` now redacts `user_excerpt` by default; explicit opt-in is required to include excerpts.
  • Routing eval validation: `POST /api/models/routing-eval` now validates `cost_weight`, `accuracy_floor`, and `accuracy_min_obs` bounds.
  • Config defaults/tests: routing defaults now use `metascore`; legacy `heuristic` input is accepted and normalized to `metascore` during validation.
  • Cache integrity mode for live agent path: semantic near-match cache reuse is now disabled in the inference pipeline (`lookup_strict`: exact + tool-TTL only) to prevent instruction-mismatched cached responses.
FEATRouting observability UX: Metrics dashboard now includes an explorable model-decision graph and a routing-profile spider graph (correctness/cost/speed) with runtime apply support via safe config patching.
FEATModel shift telemetry: Non-streaming inference pipeline now emits websocket `model_shift` events when execution model differs from selected model (fallback or cache continuity path).
FEATRouting profile roadmap spec: Added `docs/roadmap/0.9.4/features/user-routing-profile-spider-graph.md` and linked roadmap entry.
CHOREAgent message contract: `/api/agent/message` responses now expose both routing-time and execution-time model fields (`selected_model`, `model`, `model_shift_from`) for continuity diagnostics.
CHORERouting dataset privacy default: `GET /api/models/routing-dataset` now redacts `user_excerpt` by default; explicit opt-in is required to include excerpts.
CHORERouting eval validation: `POST /api/models/routing-eval` now validates `cost_weight`, `accuracy_floor`, and `accuracy_min_obs` bounds.
CHOREConfig defaults/tests: routing defaults now use `metascore`; legacy `heuristic` input is accepted and normalized to `metascore` during validation.
CHORECache integrity mode for live agent path: semantic near-match cache reuse is now disabled in the inference pipeline (`lookup_strict`: exact + tool-TTL only) to prevent instruction-mismatched cached responses.
CHOREPath normalization parity: runtime `PUT /api/config` updates now apply the same tilde (`~`) path expansion as TOML load (`normalize_paths`), including multimodal, device, and knowledge source path fields.
CHOREExplicit config path behavior: `resolve_config_path(Some(\"~/...\"))` now expands to the user home directory instead of preserving a literal `~`.
FIXLive startup migration deadlock on legacy DBs: database initialization/migration order no longer fails on `inference_costs.turn_id` index creation when the column is absent in legacy state.
FIXMigration 13 idempotency: routing v0.9.4 migration path now handles pre-existing `turn_id`/routing columns without `duplicate column` failures.
FIXStrict deny-by-default channels: adapters now reject traffic when allowlists are empty (`deny_on_empty=true`). Alpha update/mechanic flows are expected to repair channel allowlists during upgrade/install.

v0.9.2

New Features & More2026-03-02

Added: 15 changes. Changed: 7 changes. Removed: 4 changes. Key changes: Wiring Remediation (Phase 0): Comprehensive Tier 1–3 wiring audit remediation. 14 gates cleared — all functional wires verified against code. See `docs/audit/wiring-audit-v0.9.md` for the full re-audit. Unified Request Pipeline: API (`agent_message`) and channel (`process_channel_message`) paths now share `prepare_inference` + `execute_inference_pipeline` in `core.rs`, eliminating 6+ behavioral asymmetries between entry points. `post_turn_ingest` Tool Results: All call sites now pass actual tool call name + result from the ReAct loop instead of `&[]`. Episodic memory captures tool-use context, improving digest quality. Gate System Note: `build_gate_system_note` now wired in both API and channel paths (previously channel-only).

Highlights

  • Wiring Remediation (Phase 0): Comprehensive Tier 1–3 wiring audit remediation. 14 gates cleared — all functional wires verified against code. See `docs/audit/wiring-audit-v0.9.md` for the full re-audit.
  • Unified Request Pipeline: API (`agent_message`) and channel (`process_channel_message`) paths now share `prepare_inference` + `execute_inference_pipeline` in `core.rs`, eliminating 6+ behavioral asymmetries between entry points.
  • Multi-Tool Parsing: `parse_tool_calls` (plural) correctly parses multiple tool invocations from a single LLM response across all four provider formats.
  • OpenAI Responses + Google Tool Wiring: Bidirectional tool support for OpenAI Responses API and Google Generative AI — tool definitions translated into requests, structured tool calls parsed from responses with `{"tool_call": ...}` shim.
  • Quality Warm Start: `QualityTracker` is seeded from `inference_costs` on startup, eliminating cold-start assumptions for metascore routing.
  • Escalation Read Feedback: `EscalationTracker` acceptance history now feeds routing weight adjustments via `escalation_bias`, closing the feedback loop.
  • Approval Resume: Blocked tool calls are re-executed asynchronously after approval via `execute_tool_call_after_approval`.
  • Hippocampus (2.13): Self-describing schema map with auto-discovery of all system tables. Agent-created tables (`ag_<id>_*`) with access levels, row counts, and guardrails. Compact summary injected into system prompt (~200 tokens) for ambient storage awareness.
FEATWiring Remediation (Phase 0): Comprehensive Tier 1–3 wiring audit remediation. 14 gates cleared — all functional wires verified against code. See `docs/audit/wiring-audit-v0.9.md` for the full re-audit.
FEATUnified Request Pipeline: API (`agent_message`) and channel (`process_channel_message`) paths now share `prepare_inference` + `execute_inference_pipeline` in `core.rs`, eliminating 6+ behavioral asymmetries between entry points.
FEATMulti-Tool Parsing: `parse_tool_calls` (plural) correctly parses multiple tool invocations from a single LLM response across all four provider formats.
FEATOpenAI Responses + Google Tool Wiring: Bidirectional tool support for OpenAI Responses API and Google Generative AI — tool definitions translated into requests, structured tool calls parsed from responses with `{"tool_call": ...}` shim.
FEATQuality Warm Start: `QualityTracker` is seeded from `inference_costs` on startup, eliminating cold-start assumptions for metascore routing.
FEATEscalation Read Feedback: `EscalationTracker` acceptance history now feeds routing weight adjustments via `escalation_bias`, closing the feedback loop.
FEATApproval Resume: Blocked tool calls are re-executed asynchronously after approval via `execute_tool_call_after_approval`.
FEATHippocampus (2.13): Self-describing schema map with auto-discovery of all system tables. Agent-created tables (`ag_<id>_*`) with access levels, row counts, and guardrails. Compact summary injected into system prompt (~200 tokens) for ambient storage awareness.
FEATAgent Data Tools: `CreateTable`, `AlterTable`, `DropTable` registered in ToolRegistry with hippocampus auto-registration, size limits, and reserved-name enforcement.
FEATDocument Ingestion Pipeline (3.5.5): `roboticus ingest <path>` CLI and `POST /api/knowledge/ingest` API. Supports `.md`, `.txt`, `.rs`, `.py`, `.js`, `.ts`, `.pdf` files. Parse → chunk (512 tokens, 64-token overlap) → embed → store in memory system.
FEATIANA Timezone Support (1.18): Cron scheduler evaluates session reset schedules using IANA timezone identifiers. Conformance tests for DST transitions, sub-minute cron, timezone-prefixed expressions.
FEATInference Costs Extension: `latency_ms` (INTEGER), `quality_score` (REAL), `escalation` (BOOLEAN) columns added to `inference_costs` table. All inference calls now record latency and escalation state.
FEATMCP Server Gateway: First plugin release. `RoboticusMcpHandler` bridges rmcp's `ServerHandler` to the ToolRegistry. External MCP clients (Claude Desktop, Cursor, VS Code) connect via StreamableHTTP, discover tools through `tools/list`, invoke through `tools/call`. All MCP tool calls run with `InputAuthority::External`.
FEATGolden Test Fixtures: Deterministic golden files for delegation, delegation follow-up, echo follow-up, and echo tool-call pathways.
FEATTool-Call Shim Tests: Harness integration tests verifying the full structured tool_call → parse → execute → observation → follow-up pipeline.
CHORE`post_turn_ingest` Tool Results: All call sites now pass actual tool call name + result from the ReAct loop instead of `&[]`. Episodic memory captures tool-use context, improving digest quality.
CHOREGate System Note: `build_gate_system_note` now wired in both API and channel paths (previously channel-only).
CHOREShared Confidence Evaluator: `infer_with_fallback` uses the shared `LlmService.confidence` instance instead of creating a local copy.
CHOREContext Pruning: `needs_pruning()` → `soft_trim()` wired in `build_context` when assembled context exceeds the token budget.
CHORECheckpoint Load: `load_checkpoint` called during inference preparation for session resume (previously write-only).
CHOREImportance Decay: `decay_importance` called from `SessionGovernor.tick()` after digest, preventing stale context accumulation.
CHORECI Pipeline: Parallelized per-crate test execution and harness quick-test stages for faster CI runtime.
CHORE`SpawnManager`: Dead module removed (`spawning.rs` deleted, zero references). Virtual delegation tool pattern replaced it.
CHOREDead Routing Surfaces: `uniroute.rs` (ModelVector, QueryRequirements, ModelVectorRegistry) deleted. Dead selector functions (`select_for_complexity`, `select_cheapest_qualified`, `select_for_quality_target`) removed. `ModelRouter` retained as active runtime override/fallback router.
CHORE`router_integration.rs`: Dead test module removed (tested deleted routing code).
CHORE`skills-roadmap-2026.md`: Superseded by `capabilities-roadmap-2026.md`.

v0.9.1

New Features2026-03-02

Added: 6 changes. Changed: 2 changes. Key changes: Model Metascore Routing (2.19 core): Unified per-model scoring replaces availability-first routing. `ModelProfile` combines static provider attributes (cost, tier, locality) with dynamic observations (quality, capacity headroom, circuit breaker health). `metascore()` produces a transparent 5-dimension breakdown (efficacy, cost, availability, locality, confidence) with configurable weights for cost-aware mode. `select_by_metascore()` is now the primary routing decision in `select_routed_model_with_audit()`. Tiered Inference Pipeline (2.3): `ConfidenceEvaluator` scores local model responses using token probability, response length, and self-reported uncertainty signals. Responses below the confidence floor trigger automatic escalation to the next model in the fallback chain. `EscalationTracker` records escalation events for capacity/cost telemetry. Routing hot path: `select_routed_model_with_audit()` now extracts features from user content, classifies task complexity, builds model profiles, and selects via metascore — replacing the previous first-usable-model strategy. Rate limiter architecture: `GlobalRateLimitLayer` is now constructed once at startup and shared between the axum middleware stack and `AppState`, enabling admin observability of the same rate-limit counters the middleware uses.

Highlights

  • Model Metascore Routing (2.19 core): Unified per-model scoring replaces availability-first routing. `ModelProfile` combines static provider attributes (cost, tier, locality) with dynamic observations (quality, capacity headroom, circuit breaker health). `metascore()` produces a transparent 5-dimension breakdown (efficacy, cost, availability, locality, confidence) with configurable weights for cost-aware mode. `select_by_metascore()` is now the primary routing decision in `select_routed_model_with_audit()`.
  • Tiered Inference Pipeline (2.3): `ConfidenceEvaluator` scores local model responses using token probability, response length, and self-reported uncertainty signals. Responses below the confidence floor trigger automatic escalation to the next model in the fallback chain. `EscalationTracker` records escalation events for capacity/cost telemetry.
  • Throttle Event Observability (1.17): New `GET /api/stats/throttle` endpoint exposes live rate-limit counters including global/per-IP/per-actor request counts, throttle tallies, and top-10 offenders. `ThrottleSnapshot` struct provides admin visibility into abuse patterns.
  • Quality Tracking: `QualityTracker` now records observations on every inference success with a heuristic quality signal (response structure, finish reason, latency). Exponential moving average feeds into metascore efficacy dimension.
  • Audit Trail Extensions: `ModelSelectionAudit` now includes `metascore_breakdown` (full per-dimension scores) and `complexity_score` for routing decisions. `ModelCandidateAudit` includes per-candidate metascores.
  • Profile module (`roboticus-llm::profile`): `ModelProfile`, `MetascoreBreakdown`, `build_model_profiles()`, `select_by_metascore()` — 9 unit tests covering local/cloud task routing, cold-start penalties, cost-aware selection, blocked model filtering, and deterministic tie-breaking.
  • Routing hot path: `select_routed_model_with_audit()` now extracts features from user content, classifies task complexity, builds model profiles, and selects via metascore — replacing the previous first-usable-model strategy.
  • Rate limiter architecture: `GlobalRateLimitLayer` is now constructed once at startup and shared between the axum middleware stack and `AppState`, enabling admin observability of the same rate-limit counters the middleware uses.
FEATModel Metascore Routing (2.19 core): Unified per-model scoring replaces availability-first routing. `ModelProfile` combines static provider attributes (cost, tier, locality) with dynamic observations (quality, capacity headroom, circuit breaker health). `metascore()` produces a transparent 5-dimension breakdown (efficacy, cost, availability, locality, confidence) with configurable weights for cost-aware mode. `select_by_metascore()` is now the primary routing decision in `select_routed_model_with_audit()`.
FEATTiered Inference Pipeline (2.3): `ConfidenceEvaluator` scores local model responses using token probability, response length, and self-reported uncertainty signals. Responses below the confidence floor trigger automatic escalation to the next model in the fallback chain. `EscalationTracker` records escalation events for capacity/cost telemetry.
FEATThrottle Event Observability (1.17): New `GET /api/stats/throttle` endpoint exposes live rate-limit counters including global/per-IP/per-actor request counts, throttle tallies, and top-10 offenders. `ThrottleSnapshot` struct provides admin visibility into abuse patterns.
FEATQuality Tracking: `QualityTracker` now records observations on every inference success with a heuristic quality signal (response structure, finish reason, latency). Exponential moving average feeds into metascore efficacy dimension.
FEATAudit Trail Extensions: `ModelSelectionAudit` now includes `metascore_breakdown` (full per-dimension scores) and `complexity_score` for routing decisions. `ModelCandidateAudit` includes per-candidate metascores.
FEATProfile module (`roboticus-llm::profile`): `ModelProfile`, `MetascoreBreakdown`, `build_model_profiles()`, `select_by_metascore()` — 9 unit tests covering local/cloud task routing, cold-start penalties, cost-aware selection, blocked model filtering, and deterministic tie-breaking.
CHORERouting hot path: `select_routed_model_with_audit()` now extracts features from user content, classifies task complexity, builds model profiles, and selects via metascore — replacing the previous first-usable-model strategy.
CHORERate limiter architecture: `GlobalRateLimitLayer` is now constructed once at startup and shared between the axum middleware stack and `AppState`, enabling admin observability of the same rate-limit counters the middleware uses.

v0.8.9

Bug Fixes & Stability (17 changes)2026-03-01

Security: 3 changes. Fixed: 14 changes. Key changes: HIGH: RwLock held across LLM call: Config read-lock was held for the entire duration of streaming LLM calls, blocking all config writes. Now clones needed values and drops the lock before the network call. HIGH: CSS selector injection: Browser `click` and `type_text` actions now validate CSS selectors, rejecting inputs containing `{`/`}` (which can escape selector context into rule injection) and enforcing a 500-character length limit. HIGH: SSE streaming drops tool-use deltas: OpenAI-format SSE chunks with `content: null` (common in function-call and tool-use deltas) were silently dropped. Now emits an empty-string delta, matching the Anthropic and Google format arms. HIGH: Done event schema mismatch: The SSE `stream_done` event used `"content"` key while all streaming chunks used `"delta"`, causing clients to miss the done signal. Now consistently uses `"delta"`.

Highlights

  • HIGH: RwLock held across LLM call: Config read-lock was held for the entire duration of streaming LLM calls, blocking all config writes. Now clones needed values and drops the lock before the network call.
  • HIGH: CSS selector injection: Browser `click` and `type_text` actions now validate CSS selectors, rejecting inputs containing `{`/`}` (which can escape selector context into rule injection) and enforcing a 500-character length limit.
  • HIGH: Relaxed atomic ordering: Cross-task flags and counters using `Ordering::Relaxed` upgraded to `Acquire`/`Release`/`AcqRel` to ensure correct visibility guarantees across async task boundaries.
  • HIGH: SSE streaming drops tool-use deltas: OpenAI-format SSE chunks with `content: null` (common in function-call and tool-use deltas) were silently dropped. Now emits an empty-string delta, matching the Anthropic and Google format arms.
  • HIGH: Done event schema mismatch: The SSE `stream_done` event used `"content"` key while all streaming chunks used `"delta"`, causing clients to miss the done signal. Now consistently uses `"delta"`.
  • HIGH: Dead-letter replay race: Two locks acquired non-atomically during message replay could interleave with concurrent deliveries. Now holds both locks in a single scope.
  • HIGH: ReAct tool errors bypass scan_output: Error messages from tool execution were returned directly to the model without content scanning. Now calls `scan_output()` on tool error strings.
  • HIGH: derive_nickname Unicode panic: `&text[prefix.len()..]` applied a byte offset from a lowercased string to the original, panicking on multi-byte characters. Now uses `char_indices().nth()` for safe boundary detection.
FIXHIGH: RwLock held across LLM call: Config read-lock was held for the entire duration of streaming LLM calls, blocking all config writes. Now clones needed values and drops the lock before the network call.
FIXHIGH: CSS selector injection: Browser `click` and `type_text` actions now validate CSS selectors, rejecting inputs containing `{`/`}` (which can escape selector context into rule injection) and enforcing a 500-character length limit.
FIXHIGH: Relaxed atomic ordering: Cross-task flags and counters using `Ordering::Relaxed` upgraded to `Acquire`/`Release`/`AcqRel` to ensure correct visibility guarantees across async task boundaries.
FIXHIGH: SSE streaming drops tool-use deltas: OpenAI-format SSE chunks with `content: null` (common in function-call and tool-use deltas) were silently dropped. Now emits an empty-string delta, matching the Anthropic and Google format arms.
FIXHIGH: Done event schema mismatch: The SSE `stream_done` event used `"content"` key while all streaming chunks used `"delta"`, causing clients to miss the done signal. Now consistently uses `"delta"`.
FIXHIGH: Dead-letter replay race: Two locks acquired non-atomically during message replay could interleave with concurrent deliveries. Now holds both locks in a single scope.
FIXHIGH: ReAct tool errors bypass scan_output: Error messages from tool execution were returned directly to the model without content scanning. Now calls `scan_output()` on tool error strings.
FIXHIGH: derive_nickname Unicode panic: `&text[prefix.len()..]` applied a byte offset from a lowercased string to the original, panicking on multi-byte characters. Now uses `char_indices().nth()` for safe boundary detection.
FIXMED: WebSocket idle timeout missing: `handle_socket` had no timeout — idle clients held file descriptors and broadcast receivers indefinitely. Now sends ping every 30s with a 90s idle timeout.
FIXMED: Web path bypasses decomposition gate: `evaluate_decomposition_gate` was only called in `process_channel_message`, not in the web API's `agent_message`. Extracted into a shared helper called from both paths.
FIXMED: Agent processing invisible in logs: Neither `agent_message` nor `process_channel_message` logged entry spans. Added `info!` spans with session_id and channel at function entry.
FIXMED: --json flag ignored: The `--json` CLI flag was only threaded to `cmd_defrag`. Now threaded to `cmd_status` and other output-producing commands.
FIXMED: Config capabilities empty: `/api/config/capabilities` returned an empty `immutable_sections` list. Now populated with `["server", "treasury", "a2a", "wallet"]`.
FIXMED: config get returns stale TOML: `roboticus config get` read from the on-disk TOML even when the server was running with different runtime values. Now tries the live API first, falling back to TOML when offline.
FIXMED: A2A missing from channel status: `/api/channels/status` omitted the A2A channel. Now includes a hardcoded A2A entry reading enabled/listening state from server state.
FIXMED: Dashboard scheduler hardcodes agent_id: The scheduler panel used a hardcoded `agent_id: 'roboticus'` instead of the active agent. Now uses `App._activeAgentId`.
FIXLOW: Missing #[must_use] annotations: Added `#[must_use]` to 8 builder/constructor methods across `speculative.rs`, `actions.rs`, and `knowledge.rs` to prevent accidental discard of return values.

v0.8.8

Security Hardening (39 changes)2026-03-01

Security: 13 changes. Fixed: 26 changes. Key changes: HIGH: WebSocket API key leak: Replaced `?token=` query-string authentication on WebSocket upgrade with a ticket-based flow, preventing API keys from appearing in server logs, proxy logs, and browser history. HIGH: Prompt injection in tips: `get_turn_tips` and `get_session_insights` now sanitize LLM-generated tips before rendering, preventing stored prompt injection via malicious session content. HIGH: Float policy bypass: Policy enforcement on `amount` fields now falls back to `as_f64()` conversion, closing a bypass where float amounts evaded integer-only checks. HIGH: Tool call parsing failures: `parse_tool_call` now uses `rfind` with a candidate loop, correctly parsing tool calls that contain the delimiter character in arguments.

Highlights

  • HIGH: WebSocket API key leak: Replaced `?token=` query-string authentication on WebSocket upgrade with a ticket-based flow, preventing API keys from appearing in server logs, proxy logs, and browser history.
  • HIGH: Prompt injection in tips: `get_turn_tips` and `get_session_insights` now sanitize LLM-generated tips before rendering, preventing stored prompt injection via malicious session content.
  • HIGH: Provider error info leak: `classify_provider_error` in `run_llm_analysis` now strips internal details from error responses before returning to callers.
  • MED: XSS in sanitize_html: `sanitize_html` now escapes all 5 OWASP-recommended HTML entities (`& < > " '`), closing a reflected XSS vector.
  • MED: Input validation on identifiers: `peer_id`, `group_id`, and `channel` fields now enforce length and character-set constraints, preventing injection of oversized or malformed identifiers.
  • MED: Webhook body size limit: Public webhook router now applies `DefaultBodyLimit` to prevent memory exhaustion from oversized payloads.
  • MED: Analysis route DoS protection: Analysis routes now apply `ConcurrencyLimitLayer(3)` to prevent resource exhaustion from concurrent expensive LLM calls.
  • MED: Config schema leak: `update_config` error responses now return a generic message instead of leaking internal schema details.
FIXHIGH: WebSocket API key leak: Replaced `?token=` query-string authentication on WebSocket upgrade with a ticket-based flow, preventing API keys from appearing in server logs, proxy logs, and browser history.
FIXHIGH: Prompt injection in tips: `get_turn_tips` and `get_session_insights` now sanitize LLM-generated tips before rendering, preventing stored prompt injection via malicious session content.
FIXHIGH: Provider error info leak: `classify_provider_error` in `run_llm_analysis` now strips internal details from error responses before returning to callers.
FIXMED: XSS in sanitize_html: `sanitize_html` now escapes all 5 OWASP-recommended HTML entities (`& < > " '`), closing a reflected XSS vector.
FIXMED: Input validation on identifiers: `peer_id`, `group_id`, and `channel` fields now enforce length and character-set constraints, preventing injection of oversized or malformed identifiers.
FIXMED: Webhook body size limit: Public webhook router now applies `DefaultBodyLimit` to prevent memory exhaustion from oversized payloads.
FIXMED: Analysis route DoS protection: Analysis routes now apply `ConcurrencyLimitLayer(3)` to prevent resource exhaustion from concurrent expensive LLM calls.
FIXMED: Config schema leak: `update_config` error responses now return a generic message instead of leaking internal schema details.
FIXMED: Feedback comment size limit: `FeedbackRequest.comment` now enforces a 4096-character cap, preventing oversized payloads from reaching storage.
FIXMED: Config allowlist tightening: Removed `extra_headers` from the `get_config` response allowlist, preventing exposure of sensitive header values.
FIXLOW: Unsafe UTF-8 decode: Replaced `from_utf8_unchecked` with safe `from_utf8` to prevent undefined behavior on malformed input.
FIXLOW: Embedding test env isolation: Embedding test uses a unique env var name with a SAFETY comment to prevent cross-test interference.
FIXLOW: Path traversal defense-in-depth: `obsidian_read` now validates paths against directory traversal patterns as an additional defense layer.
FIXHIGH: Float policy bypass: Policy enforcement on `amount` fields now falls back to `as_f64()` conversion, closing a bypass where float amounts evaded integer-only checks.
FIXHIGH: Tool call parsing failures: `parse_tool_call` now uses `rfind` with a candidate loop, correctly parsing tool calls that contain the delimiter character in arguments.
FIXHIGH: Unicode string metric: `common_prefix_ratio` now operates on `chars()` instead of byte slices, producing correct ratios for multi-byte characters.
FIXHIGH: Incorrect P50 latency: `latency_p50` now computes the true median by averaging the two middle values for even-length arrays.
FIXHIGH: Speculation cache collisions: `SpeculationKey` now stores full parameter JSON instead of using `DefaultHasher`, which was not stable across processes and caused incorrect cache hits.
FIXHIGH: WhatsApp adapter panic: `WhatsAppAdapter::new` now returns `Result<Self>` instead of panicking on initialization failures.
FIXHIGH: Export agents silent failure: `export_agents` now matches on `Result` and propagates errors instead of silently dropping them.
FIXHIGH: Inference cost logging: `record_inference_cost` now uses `inspect_err` to log failures instead of silently discarding them with `.ok()`.
FIXMED: Turn count inflation: `turn_count` now only increments on `Think` state transitions, fixing 2-3x count inflation from duplicate counting.
FIXMED: Archive truncation: `compact_before_archive` now fetches all messages instead of being capped at 20, preventing data loss during session archival.
FIXMED: URL decoder corruption: `%XX` decoder now preserves characters on invalid hex sequences instead of silently dropping them.
FIXMED: Task handoff stalls: Handoff logic now skips `Failed` tasks to find the next `Pending` task, preventing the scheduler from stalling on failed work.
FIXMED: Config write propagation: `write_defaults` now propagates errors with `?` instead of silently discarding them with `.ok()`.
FIXMED: Cron validation logging: Invalid cron expressions now log a warning before returning `false`, replacing a silent rejection.
FIXMED: Wallet passphrase fallthrough: An incorrect `ROBOTICUS_WALLET_PASSPHRASE` now produces a hard error instead of silently falling through to the default passphrase.
FIXMED: Config/session export errors: `to_string_pretty` failures in config/session export now return proper error responses instead of empty bodies.
FIXMED: Corrupt skills warning: Corrupt `skills_json` values now log a warning instead of being silently ignored.
FIXMED: Translation request errors: `translate_request` failures now return HTTP 500 with a proper error body instead of an empty response.
FIXMED: Translation response errors: `translate_response` failures now return HTTP 502 with a descriptive message instead of `"(no response)"`.
FIXLOW: Loop detection consolidation: Removed redundant `is_looping` pre-check, consolidating loop detection into a single code path.
FIXLOW: Archive count accuracy: `rotate_agent_scope_sessions` now returns the actual archived count instead of a potentially incorrect value.
FIXLOW: Token parse overflow: Token parsing now uses saturating `u32` casts, capping at `u32::MAX` instead of panicking on overflow.
FIXLOW: Subtask dedup ordering: `split_subtasks` now uses a `HashSet` for order-preserving deduplication instead of unstable dedup.
FIXLOW: Session row corruption logging: Corrupted session rows now log a warning instead of being silently dropped during iteration.
FIXLOW: DB error logging for cost queries: Database errors in turn-query average cost calculations are now logged instead of silently ignored.
FIXLOW: Defrag read error handling: File defragmentation now skips files on read error with a warning instead of substituting an empty string.

v0.8.7

Bug Fixes & Stability (21 changes)2026-02-28

Fixed: 19 changes. Added: 2 changes. Key changes: CRIT: Cron jobs silently never firing: `run_cron_worker` timestamp format lacked timezone suffix (`Z`), causing `evaluate_cron` RFC 3339 parse to always fail — all cron-scheduled jobs were silently skipped. HIGH: Telegram chunk_message UTF-8 panic: Byte-level string slicing in `chunk_message` panicked on multi-byte characters (emoji, CJK). Now uses `floor_char_boundary()` matching the Discord adapter. Release notes for v0.8.5 and v0.8.6 (missing from previous releases, blocking release doc gate). Roadmap section 1.24: Built-in CLI Agent Skills (Claude Code + Codex CLI).

Highlights

  • CRIT: Cron jobs silently never firing: `run_cron_worker` timestamp format lacked timezone suffix (`Z`), causing `evaluate_cron` RFC 3339 parse to always fail — all cron-scheduled jobs were silently skipped.
  • HIGH: Telegram chunk_message UTF-8 panic: Byte-level string slicing in `chunk_message` panicked on multi-byte characters (emoji, CJK). Now uses `floor_char_boundary()` matching the Discord adapter.
  • HIGH: Keystore redact_key_name UTF-8 panic: Byte-level `&key[..3]` slicing panicked on multi-byte key names. Now uses `key.chars().take(3)`.
  • HIGH: LLM forward_stream missing query: auth mode: Streaming requests to providers using query-string authentication (e.g., Google Generative AI) failed because the `query:` prefix was not handled, sending it as a literal HTTP header instead.
  • HIGH: yield_engine U256-to-u64 panic: `real_a_token_balance` panicked via `U256::to::<u64>()` if an aToken balance exceeded `u64::MAX`. Now uses safe `try_into::<u128>()`.
  • HIGH: yield_engine amount_to_raw saturation: `amount_to_raw` silently saturated USDC amounts above ~$18.4B via unchecked `f64 -> u64` cast. Now explicitly clamps.
  • MED: Email adapter SMTP relay panic: `EmailAdapter::new` panicked via `.expect()` on invalid SMTP hostname. Now returns `Result`.
  • MED: Email adapter mutex panics: `push_message`/`recv` used `.expect("mutex poisoned")`. Now uses `.unwrap_or_else(|e| e.into_inner())` for poison recovery, matching other adapters.
FIXCRIT: Cron jobs silently never firing: `run_cron_worker` timestamp format lacked timezone suffix (`Z`), causing `evaluate_cron` RFC 3339 parse to always fail — all cron-scheduled jobs were silently skipped.
FIXHIGH: Telegram chunk_message UTF-8 panic: Byte-level string slicing in `chunk_message` panicked on multi-byte characters (emoji, CJK). Now uses `floor_char_boundary()` matching the Discord adapter.
FIXHIGH: Keystore redact_key_name UTF-8 panic: Byte-level `&key[..3]` slicing panicked on multi-byte key names. Now uses `key.chars().take(3)`.
FIXHIGH: LLM forward_stream missing query: auth mode: Streaming requests to providers using query-string authentication (e.g., Google Generative AI) failed because the `query:` prefix was not handled, sending it as a literal HTTP header instead.
FIXHIGH: yield_engine U256-to-u64 panic: `real_a_token_balance` panicked via `U256::to::<u64>()` if an aToken balance exceeded `u64::MAX`. Now uses safe `try_into::<u128>()`.
FIXHIGH: yield_engine amount_to_raw saturation: `amount_to_raw` silently saturated USDC amounts above ~$18.4B via unchecked `f64 -> u64` cast. Now explicitly clamps.
FIXMED: Email adapter SMTP relay panic: `EmailAdapter::new` panicked via `.expect()` on invalid SMTP hostname. Now returns `Result`.
FIXMED: Email adapter mutex panics: `push_message`/`recv` used `.expect("mutex poisoned")`. Now uses `.unwrap_or_else(|e| e.into_inner())` for poison recovery, matching other adapters.
FIXMED: Discord GatewayConnection mutex panics: All 4 accessor methods used `.expect("mutex poisoned")`. Now uses poison recovery matching the rest of the Discord adapter.
FIXMED: CDP client initialization panic: `CdpClient::new` panicked via `.expect()` on TLS cert issues. Now returns `Result`.
FIXMED: Embedding URL double API key: When both Google format and `query:` auth were active, the API key was appended twice. Made the two paths mutually exclusive.
FIXMED: Embedding URL missing percent-encoding: API keys were interpolated into URLs without encoding. Now uses `pct_encode_query_value`.
FIXMED: Hippocampus Unicode/ASCII mismatch: `create_agent_table` allowed Unicode alphanumeric characters but `drop_agent_table` required ASCII-only, creating undeletable tables. Both now require ASCII.
FIXMED: Skills reload counters wrong on failure: `added`/`updated` counters incremented even when DB operations failed. Now only increment on success.
FIXMED: Skills rollback silent failures: File rollback operations used `let _ =` silently. Now log errors at error level.
FIXLOW: sanitize_platform mixed byte/char units: Truncation used `.chars().take()` (char count) after a `.len()` (byte count) guard. Now truncates at byte boundary consistently.
FIXLOW: mock_tx_hash f64 saturation: Used `amount * 1e18` (overflows u64 above ~18.4). Changed to USDC scale (1e6).
FIXLOW: Session model column never populated: `update_model()` was not called after LLM routing, leaving the `sessions.model` column perpetually NULL.
FIXLOW: Moonshot/Kimi tier misclassified: `classify()` in `tier.rs` did not match `moonshot` or `kimi` substrings, causing Kimi K2 models to fall through to the T2 default instead of T3.
FEATRelease notes for v0.8.5 and v0.8.6 (missing from previous releases, blocking release doc gate).
FEATRoadmap section 1.24: Built-in CLI Agent Skills (Claude Code + Codex CLI).

v0.8.6

Security Hardening & More2026-02-28

Security: 9 changes. Fixed: 14 changes. Added: 2 changes. Key changes: CRIT: Unauthenticated rate-limit actor identity: Removed `x-user-id` header as rate-limit actor identity — it was unauthenticated and trivially spoofable. CRIT: Stable token fingerprinting: Replaced `DefaultHasher` with SHA-256 for token fingerprinting, since `DefaultHasher` is not stable across processes and could cause cache/rate-limit bypasses. Windows daemon error propagation: `schtasks /Create` errors now propagate instead of being silently dropped; post-spawn verification added; `schtasks /Delete` errors during uninstall handled correctly. CLI API key headers: Added `--api-key`/`ROBOTICUS_API_KEY` global CLI argument. All 22 bare `reqwest` calls replaced with `http_client()` helper that injects API key as default header.

Highlights

  • CRIT: Unauthenticated rate-limit actor identity: Removed `x-user-id` header as rate-limit actor identity — it was unauthenticated and trivially spoofable.
  • CRIT: Stable token fingerprinting: Replaced `DefaultHasher` with SHA-256 for token fingerprinting, since `DefaultHasher` is not stable across processes and could cause cache/rate-limit bypasses.
  • HIGH: Rate-limit IP fallback: IP extraction now uses `ConnectInfo<SocketAddr>` (real TCP peer address) instead of a hardcoded `127.0.0.1` fallback.
  • HIGH: ASCII-only identifiers: `validate_identifier` now restricts to ASCII alphanumeric characters, closing Unicode homoglyph and normalization attacks.
  • HIGH: Memory search query cap: `/api/memory/search` query parameter capped at 512 characters to prevent regex-based DoS.
  • HIGH: Error message sanitization: Added SQLite schema-leaking prefixes (`no such table`, `no such column`, etc.) to the error sanitization blocklist.
  • MED: Rate-limit counter ordering: Global rate-limit counter now incremented after per-IP/per-actor checks pass, preventing global exhaustion from blocked IPs.
  • MED: Symlink-safe directory traversal: `collect_findings_recursive` now uses `entry.file_type()` and skips symlinks, preventing symlink-following attacks.
FIXCRIT: Unauthenticated rate-limit actor identity: Removed `x-user-id` header as rate-limit actor identity — it was unauthenticated and trivially spoofable.
FIXCRIT: Stable token fingerprinting: Replaced `DefaultHasher` with SHA-256 for token fingerprinting, since `DefaultHasher` is not stable across processes and could cause cache/rate-limit bypasses.
FIXHIGH: Rate-limit IP fallback: IP extraction now uses `ConnectInfo<SocketAddr>` (real TCP peer address) instead of a hardcoded `127.0.0.1` fallback.
FIXHIGH: ASCII-only identifiers: `validate_identifier` now restricts to ASCII alphanumeric characters, closing Unicode homoglyph and normalization attacks.
FIXHIGH: Memory search query cap: `/api/memory/search` query parameter capped at 512 characters to prevent regex-based DoS.
FIXHIGH: Error message sanitization: Added SQLite schema-leaking prefixes (`no such table`, `no such column`, etc.) to the error sanitization blocklist.
FIXMED: Rate-limit counter ordering: Global rate-limit counter now incremented after per-IP/per-actor checks pass, preventing global exhaustion from blocked IPs.
FIXMED: Symlink-safe directory traversal: `collect_findings_recursive` now uses `entry.file_type()` and skips symlinks, preventing symlink-following attacks.
FIXMED: WhatsApp HMAC raw byte comparison: HMAC verification now compares raw bytes instead of hex string representations, closing timing side-channels from variable-length hex comparison.
FIXWindows daemon error propagation: `schtasks /Create` errors now propagate instead of being silently dropped; post-spawn verification added; `schtasks /Delete` errors during uninstall handled correctly.
FIXCLI API key headers: Added `--api-key`/`ROBOTICUS_API_KEY` global CLI argument. All 22 bare `reqwest` calls replaced with `http_client()` helper that injects API key as default header.
FIXFlaky test elimination: Replaced TOCTOU ephemeral port test with RFC 5737 TEST-NET-1 address (192.0.2.1) for deterministic unreachable-port testing.
FIXBundled providers parse failure (F5): Changed `.unwrap_or_default()` to `.expect()` — bundled TOML is build-time data; parse failure means the binary is broken and should panic fast.
FIXUpdate state save errors (F3): Three `state.save().ok()` sites now log errors before discarding, plus update state load now logs parse/read failures.
FIXLegacy Windows service cleanup (F7): `sc.exe stop/delete` errors during legacy cleanup now logged at debug level instead of silently dropped.
FIXOAuth token resolution (F8): `resolve_token().ok()` now logs failures, surfacing OAuth refresh errors that were previously invisible.
FIXTranslate request error propagation (F9): `translate_request` errors now return HTTP 400 instead of falling back to an empty JSON body.
FIXCorrupted cost row logging (F10): `filter_map(|r| r.ok())` on cost query rows now logs dropped rows.
FIXEmbedding failure logging (F12): Three `embed_single().ok()` sites now log failures, making RAG degradation visible.
FIXDefrag stdout write errors (F14): JSON stdout writes now propagate `io::Error` instead of silently dropping.
FIXSession nickname update (F19): `update_nickname().ok()` now logs failures.
FIXRecommendation inference cost (F20): `record_inference_cost().ok()` now logs failures.
FIXAgent status query errors: Tool call and turn queries in agent status now log errors at debug level.
FEATAuth middleware roundtrip tests: wrong key rejection, no-auth passthrough, POST method coverage.
FEATSSE streaming endpoint validation tests: empty content, oversized content, missing fields.

v0.8.5

Bug Fixes & Stability (28 changes)2026-02-28

Security: 6 changes. Fixed: 22 changes. Key changes: WASM preemptive timeout (BUG-101): WASM plugin execution now runs on a dedicated thread with `recv_timeout`, providing true preemptive timeout instead of the previous post-hoc elapsed-time check that allowed malicious modules to run indefinitely. Script runner orphan kill (BUG-102): Script runner now captures the child PID before `wait_with_output()` and sends `kill -9` on timeout, preventing orphan process accumulation. reqwest Client panic (BUG-105): `VectorDbSource::new()` and `GraphSource::new()` now return `Result` instead of panicking via `.expect()` when TLS initialization fails. Signal handler crash (BUG-108): SIGTERM handler installation now falls back to SIGINT-only mode instead of crashing via `.expect()` in containerized environments.

Highlights

  • WASM preemptive timeout (BUG-101): WASM plugin execution now runs on a dedicated thread with `recv_timeout`, providing true preemptive timeout instead of the previous post-hoc elapsed-time check that allowed malicious modules to run indefinitely.
  • Script runner orphan kill (BUG-102): Script runner now captures the child PID before `wait_with_output()` and sends `kill -9` on timeout, preventing orphan process accumulation.
  • Rate limiter memory bounds (BUG-103): Per-IP and per-actor rate limit maps are now capped at 10,000 and 5,000 entries respectively, preventing unbounded memory growth during distributed floods. Throttle tracking maps are also cleared on window reset.
  • Knowledge/Obsidian bounded reads (BUG-104, BUG-110): `DirectorySource::query()` and `parse_note()` now enforce 10 MB and 5 MB file size limits respectively, preventing OOM on oversized files.
  • Config secret allowlist (BUG-106): Admin config endpoint now uses an allowlist (`ALLOWED_FIELDS`) instead of a blocklist for field filtering, ensuring new secret fields are safe by default.
  • Interview turn cap (BUG-107): Interview sessions now enforce a 200-turn maximum to prevent unbounded memory growth within the 3600s TTL.
  • reqwest Client panic (BUG-105): `VectorDbSource::new()` and `GraphSource::new()` now return `Result` instead of panicking via `.expect()` when TLS initialization fails.
  • Signal handler crash (BUG-108): SIGTERM handler installation now falls back to SIGINT-only mode instead of crashing via `.expect()` in containerized environments.
FIXWASM preemptive timeout (BUG-101): WASM plugin execution now runs on a dedicated thread with `recv_timeout`, providing true preemptive timeout instead of the previous post-hoc elapsed-time check that allowed malicious modules to run indefinitely.
FIXScript runner orphan kill (BUG-102): Script runner now captures the child PID before `wait_with_output()` and sends `kill -9` on timeout, preventing orphan process accumulation.
FIXRate limiter memory bounds (BUG-103): Per-IP and per-actor rate limit maps are now capped at 10,000 and 5,000 entries respectively, preventing unbounded memory growth during distributed floods. Throttle tracking maps are also cleared on window reset.
FIXKnowledge/Obsidian bounded reads (BUG-104, BUG-110): `DirectorySource::query()` and `parse_note()` now enforce 10 MB and 5 MB file size limits respectively, preventing OOM on oversized files.
FIXConfig secret allowlist (BUG-106): Admin config endpoint now uses an allowlist (`ALLOWED_FIELDS`) instead of a blocklist for field filtering, ensuring new secret fields are safe by default.
FIXInterview turn cap (BUG-107): Interview sessions now enforce a 200-turn maximum to prevent unbounded memory growth within the 3600s TTL.
FIXreqwest Client panic (BUG-105): `VectorDbSource::new()` and `GraphSource::new()` now return `Result` instead of panicking via `.expect()` when TLS initialization fails.
FIXSignal handler crash (BUG-108): SIGTERM handler installation now falls back to SIGINT-only mode instead of crashing via `.expect()` in containerized environments.
FIXHeartbeat unreachable panic (BUG-109): `interval_for_tier()` catch-all arm now returns a safe default (`interval_ms * 2`) instead of `unreachable!()`, preventing runtime panics if new `SurvivalTier` variants are added.
FIXRegex recompilation (BUG-111): Obsidian tag and wikilink regexes are now `LazyLock` statics instead of being recompiled on every invocation.
FIXBudget float precision (BUG-112): `record_spending()` now uses epsilon-aware comparison to avoid IEEE 754 rounding errors causing spurious over-budget rejections.
FIXSub-agent lifecycle failures (SF-15–SF-20): All `let _ =` patterns on `registry.register()`, `start_agent()`, `stop_agent()`, `unregister()`, and `assign_agent()` now log errors at appropriate levels.
FIXAPI key env var diagnostics (SF-21, SF-22): Empty and missing API key / email password environment variables now produce warn-level log messages instead of silently returning empty strings.
FIXSub-agent list errors (SF-23): `list_sub_agents` DB errors now propagate at the delegation entry point and log at remaining fallback sites.
FIXSkills list errors (SF-24): `list_skills` DB failure now logged before fallback.
FIXMCP discovery failure (SF-25): MCP client discovery errors at startup now logged at warn level.
FIXSemantic cache load failure (SF-26): Cache load errors now logged before fallback to empty.
FIXProvider key resolution (SF-27): Missing provider keys for non-local providers now produce warn-level diagnostics.
FIXBundled providers parse failure (SF-28): TOML parse errors for bundled providers now logged.
FIXConfig backup restore (SF-29): Failed hot-reload backup restoration now logged at error level.
FIXMigration SQL errors (SF-30): SQL execution failures during migration now surfaced as warnings.
FIXThinking indicator failures (SF-31): Channel thinking indicator send failures now logged at debug level across all 4 platforms.
FIXSession candidates JSON (SF-32): Model selection candidate deserialization errors now logged.
FIXTelegram API errors (SF-33): Typing indicator and message delete HTTP failures now logged at debug level.
FIXSession counts fallback (SF-34): Sub-agent session count DB errors now logged before fallback.
FIXSubtask JSON parse (SF-35): Malformed `subtasks` parameter (non-array) now produces a warning instead of silently returning empty.
FIX19 additional MEDIUM silent failures (SF-36–SF-52): Error logging added across oauth, plugin-sdk, retrieval, digest, skills, signal, discord, whatsapp, sessions, defrag, embedding, main CLI, keystore, and obsidian modules.
FIXMigration export cascade (SF-48): Channel export now properly reports file read failures and JSON serialization errors instead of silently producing empty output.

v0.8.4

Bug Fixes & Stability & More2026-02-28

Security: 3 changes. Fixed: 16 changes. Changed: 1 change. Key changes: WebSocket message size limit: Unauthenticated WebSocket connections now enforce a 4 KiB inbound message limit and no longer echo full message bodies, closing a ~3x memory amplification DoS vector. Hippocampus TOCTOU fix: `drop_agent_table` auth check and DROP are now wrapped in a single transaction, preventing race-condition bypasses. Agent amnesia on DB error (SF-2): `list_messages` calls in agent routes now propagate errors instead of silently returning empty history via `.unwrap_or_default()`. Governor silent write failures (SF-1): Session expiry and compaction errors are now logged at warn/error level; `tick()` returns an accurate expired count instead of silently swallowing failures with `.ok()`.

Highlights

  • WebSocket message size limit: Unauthenticated WebSocket connections now enforce a 4 KiB inbound message limit and no longer echo full message bodies, closing a ~3x memory amplification DoS vector.
  • Hippocampus TOCTOU fix: `drop_agent_table` auth check and DROP are now wrapped in a single transaction, preventing race-condition bypasses.
  • Script runner bounded reads: Shebang detection now uses `BufReader::take(512)` instead of `read_to_string`, preventing OOM on oversized script files.
  • Agent amnesia on DB error (SF-2): `list_messages` calls in agent routes now propagate errors instead of silently returning empty history via `.unwrap_or_default()`.
  • Governor silent write failures (SF-1): Session expiry and compaction errors are now logged at warn/error level; `tick()` returns an accurate expired count instead of silently swallowing failures with `.ok()`.
  • Money::from_dollars NaN panic (BUG-2): `from_dollars` now returns `Result`, rejecting NaN and Infinity inputs instead of panicking via `assert!`.
  • Delivery queue recovery (SF-7): `recover_from_store` is now async with proper `.lock().await`, replacing a `try_lock()` that silently dropped recovered messages.
  • Agent loop detection enforcement (BUG-3): `is_looping()` is now called inside `transition()` and forces `Done` state, preventing callers from bypassing loop detection.
FIXWebSocket message size limit: Unauthenticated WebSocket connections now enforce a 4 KiB inbound message limit and no longer echo full message bodies, closing a ~3x memory amplification DoS vector.
FIXHippocampus TOCTOU fix: `drop_agent_table` auth check and DROP are now wrapped in a single transaction, preventing race-condition bypasses.
FIXScript runner bounded reads: Shebang detection now uses `BufReader::take(512)` instead of `read_to_string`, preventing OOM on oversized script files.
FIXAgent amnesia on DB error (SF-2): `list_messages` calls in agent routes now propagate errors instead of silently returning empty history via `.unwrap_or_default()`.
FIXGovernor silent write failures (SF-1): Session expiry and compaction errors are now logged at warn/error level; `tick()` returns an accurate expired count instead of silently swallowing failures with `.ok()`.
FIXMoney::from_dollars NaN panic (BUG-2): `from_dollars` now returns `Result`, rejecting NaN and Infinity inputs instead of panicking via `assert!`.
FIXDelivery queue recovery (SF-7): `recover_from_store` is now async with proper `.lock().await`, replacing a `try_lock()` that silently dropped recovered messages.
FIXAgent loop detection enforcement (BUG-3): `is_looping()` is now called inside `transition()` and forces `Done` state, preventing callers from bypassing loop detection.
FIXDigit-leading SQL identifiers (BUG-7): `validate_identifier` now rejects names starting with digits, which would produce invalid SQL.
FIXEmbedding API key error message (SF-4): Missing API key env var now returns a clear error message instead of a cryptic 401 via `.unwrap_or_default()`.
FIXANN index corruption paths (SF-6, SF-10): Corrupt embedding JSON is now logged and skipped; RwLock poison on write returns an error instead of silently recovering with stale data.
FIXAdmin dashboard false empties (SF-3): DB read errors in dashboard endpoints are now logged with `inspect_err` before falling back to defaults, enabling diagnosis.
FIXSession tool call queries (SF-9): Tool call endpoints now propagate DB errors with proper HTTP 500 responses instead of returning empty arrays.
FIXEventBus publish logging (SF-5): `let _ =` on channel send replaced with debug-level logging when no subscribers are active.
FIXDelivery queue timestamp fallback (SF-11): Failed timestamp parse now falls back to `UNIX_EPOCH` (safe backoff) instead of `Utc::now()` (immediate retry).
FIXDead letter false empties (SF-8): `dead_letters_from_store` errors now logged before fallback.
FIXAdmin config serialization (SF-12): Config endpoint returns HTTP 500 on serialization failure instead of null body.
FIXEfficiency report serialization (SF-13): Efficiency endpoint returns HTTP 500 on serialization failure instead of null body.
FIXWebhook body bytes (SF-14): Failed body extraction now logs a warning instead of silently discarding the payload.
CHORECrate publish ordering: Release workflow now publishes crates in correct topological dependency order with increased index propagation wait times, fixing the v0.8.3 publish failure.

v0.8.3

Security Hardening & More2026-02-27

Security: 4 changes. Fixed: 4 changes. Added: 1 change. Key changes: Auth bypass when no API key: Requests to non-exempt API routes now fail closed when no API key is configured — only loopback connections are allowed. Previously, missing API key config silently allowed all traffic. A2A replay protection: Added nonce registry with TTL-based expiry to the A2A protocol, preventing message replay attacks within the nonce window. UTF-8 panic in memory truncation: Replaced unsafe byte-level string slicing with `floor_char_boundary()` to prevent panics on multi-byte characters (emoji, CJK) near the 200-char truncation point. Script plugin zombie processes: Script timeout now explicitly kills the child process and reaps it, preventing zombie accumulation.

Highlights

  • Auth bypass when no API key: Requests to non-exempt API routes now fail closed when no API key is configured — only loopback connections are allowed. Previously, missing API key config silently allowed all traffic.
  • A2A replay protection: Added nonce registry with TTL-based expiry to the A2A protocol, preventing message replay attacks within the nonce window.
  • Plugin permission enforcement: New `strict_permissions` and `allowed_permissions` config fields for plugin policy. In strict mode, undeclared permissions are blocked; in permissive mode (default), they produce a warning.
  • Ethereum signature recovery ID: EIP-191 signatures now include the recovery byte (v = 27 or 28), producing correct 65-byte signatures instead of 64-byte truncated ones.
  • UTF-8 panic in memory truncation: Replaced unsafe byte-level string slicing with `floor_char_boundary()` to prevent panics on multi-byte characters (emoji, CJK) near the 200-char truncation point.
  • Script plugin zombie processes: Script timeout now explicitly kills the child process and reaps it, preventing zombie accumulation.
  • Script plugin unbounded output: stdout/stderr from plugin scripts are now capped at 10 MB via `AsyncReadExt::take()`.
  • Keystore lock ordering: Consolidated two separate mutexes into a single `KeystoreState` mutex, eliminating potential deadlock scenarios.
FIXAuth bypass when no API key: Requests to non-exempt API routes now fail closed when no API key is configured — only loopback connections are allowed. Previously, missing API key config silently allowed all traffic.
FIXA2A replay protection: Added nonce registry with TTL-based expiry to the A2A protocol, preventing message replay attacks within the nonce window.
FIXPlugin permission enforcement: New `strict_permissions` and `allowed_permissions` config fields for plugin policy. In strict mode, undeclared permissions are blocked; in permissive mode (default), they produce a warning.
FIXEthereum signature recovery ID: EIP-191 signatures now include the recovery byte (v = 27 or 28), producing correct 65-byte signatures instead of 64-byte truncated ones.
FIXUTF-8 panic in memory truncation: Replaced unsafe byte-level string slicing with `floor_char_boundary()` to prevent panics on multi-byte characters (emoji, CJK) near the 200-char truncation point.
FIXScript plugin zombie processes: Script timeout now explicitly kills the child process and reaps it, preventing zombie accumulation.
FIXScript plugin unbounded output: stdout/stderr from plugin scripts are now capped at 10 MB via `AsyncReadExt::take()`.
FIXKeystore lock ordering: Consolidated two separate mutexes into a single `KeystoreState` mutex, eliminating potential deadlock scenarios.
FEAT`roboticus defrag` command: New workspace coherence scanner with 6 passes — refs (dead reference elimination), drift (config drift detection), artifacts (orphaned file cleanup), stale (ghost state entry removal), identity (brand consistency), and scripts (script health validation). Supports `--fix` for auto-repair, `--yes` for non-interactive mode, and `--json` for machine-readable output.

v0.8.2

New Features2026-02-27

Added: 3 changes. Fixed: 5 changes. Key changes: 100+ API route integration tests: Comprehensive test coverage for sessions, turns, interviews, feedback, skills, model selection, channels, webhooks, dead letters, admin, memory, cron, context, and approvals endpoints. Tests exercise both success and error paths including validation, 404s, auth, and edge cases. Workspace test count now at 3,316. Homebrew tap distribution: macOS/Linux users can install via `brew install robot-accomplice/tap/roboticus`. 29 stabilization bug fixes: Resolved input validation gaps, API error format inconsistencies, query parameter hardening, security headers, dashboard trailing content, model persistence, cron field naming, and Windows TOML path issues discovered during exhaustive hands-on testing of v0.8.1. HTML injection prevention: Closed remaining sanitization coverage gaps in API write endpoints.

Highlights

  • 100+ API route integration tests: Comprehensive test coverage for sessions, turns, interviews, feedback, skills, model selection, channels, webhooks, dead letters, admin, memory, cron, context, and approvals endpoints. Tests exercise both success and error paths including validation, 404s, auth, and edge cases. Workspace test count now at 3,316.
  • Homebrew tap distribution: macOS/Linux users can install via `brew install robot-accomplice/tap/roboticus`.
  • Winget package distribution: Windows users can install via Winget package manager.
  • 29 stabilization bug fixes: Resolved input validation gaps, API error format inconsistencies, query parameter hardening, security headers, dashboard trailing content, model persistence, cron field naming, and Windows TOML path issues discovered during exhaustive hands-on testing of v0.8.1.
  • HTML injection prevention: Closed remaining sanitization coverage gaps in API write endpoints.
  • Dashboard SPA cleanup: Removed duplicate trailing content after `</html>` close tag.
  • Model change persistence: Fixed model selection not persisting across server restarts.
  • Config serialization: Fixed TOML config serialization on Windows paths.
FEAT100+ API route integration tests: Comprehensive test coverage for sessions, turns, interviews, feedback, skills, model selection, channels, webhooks, dead letters, admin, memory, cron, context, and approvals endpoints. Tests exercise both success and error paths including validation, 404s, auth, and edge cases. Workspace test count now at 3,316.
FEATHomebrew tap distribution: macOS/Linux users can install via `brew install robot-accomplice/tap/roboticus`.
FEATWinget package distribution: Windows users can install via Winget package manager.
FIX29 stabilization bug fixes: Resolved input validation gaps, API error format inconsistencies, query parameter hardening, security headers, dashboard trailing content, model persistence, cron field naming, and Windows TOML path issues discovered during exhaustive hands-on testing of v0.8.1.
FIXHTML injection prevention: Closed remaining sanitization coverage gaps in API write endpoints.
FIXDashboard SPA cleanup: Removed duplicate trailing content after `</html>` close tag.
FIXModel change persistence: Fixed model selection not persisting across server restarts.
FIXConfig serialization: Fixed TOML config serialization on Windows paths.

v0.8.1

Bug Fixes & Stability (14 changes)2026-02-27

Fixed: 12 changes. Changed: 2 changes. Key changes: 40 smoke/UAT bug fixes: Resolved 40 bugs (5 critical, 6 high, 15 medium, 14 low/UX) discovered during comprehensive smoke testing of all 85 REST routes, 32 CLI commands, and 13 dashboard pages. Input validation hardening: Added field-length limits, HTML sanitization, and null-byte rejection across all API write endpoints. CI scripts use POSIX grep: Replaced all `rg` (ripgrep) invocations with standard `grep -E`/`grep -qE` in CI scripts for broader runner compatibility. Windows compilation: Added conditional `allow(unused_mut)` for platform-gated mutation in security audit command.

Highlights

  • 40 smoke/UAT bug fixes: Resolved 40 bugs (5 critical, 6 high, 15 medium, 14 low/UX) discovered during comprehensive smoke testing of all 85 REST routes, 32 CLI commands, and 13 dashboard pages.
  • Input validation hardening: Added field-length limits, HTML sanitization, and null-byte rejection across all API write endpoints.
  • JSON error responses: All API error paths now return structured `{"error": "..."}` JSON instead of plain text.
  • Memory search deduplication: FTS memory search no longer returns duplicate entries; results are now structured with category/timestamp metadata.
  • Cron scheduler accuracy: `next_run_at` is now persisted after computation; heartbeat no longer floods logs with virtual job IDs; jobs use actual agent IDs.
  • Cost display precision: Floating-point noise eliminated from cost/efficiency metrics (rounded to 6 decimal places with division-by-zero guard).
  • Skills metadata: `risk_level` is now parameterized (not hardcoded "Caution"); skills track `last_loaded_at` timestamp.
  • CLI resilience: `roboticus check` no longer crashes with raw Rust IO errors; shows friendly messages with config path suggestions.
FIX40 smoke/UAT bug fixes: Resolved 40 bugs (5 critical, 6 high, 15 medium, 14 low/UX) discovered during comprehensive smoke testing of all 85 REST routes, 32 CLI commands, and 13 dashboard pages.
FIXInput validation hardening: Added field-length limits, HTML sanitization, and null-byte rejection across all API write endpoints.
FIXJSON error responses: All API error paths now return structured `{"error": "..."}` JSON instead of plain text.
FIXMemory search deduplication: FTS memory search no longer returns duplicate entries; results are now structured with category/timestamp metadata.
FIXCron scheduler accuracy: `next_run_at` is now persisted after computation; heartbeat no longer floods logs with virtual job IDs; jobs use actual agent IDs.
FIXCost display precision: Floating-point noise eliminated from cost/efficiency metrics (rounded to 6 decimal places with division-by-zero guard).
FIXSkills metadata: `risk_level` is now parameterized (not hardcoded "Caution"); skills track `last_loaded_at` timestamp.
FIXCLI resilience: `roboticus check` no longer crashes with raw Rust IO errors; shows friendly messages with config path suggestions.
FIXDashboard UX: Fixed 14 display bugs including schedule text duplication, raw-seconds uptime, missing pagination, broken status indicators, and external font dependency removal.
FIXFilesystem path exposure: Skills API no longer leaks `source_path`/`script_path` in responses.
FIXSession creation response: `POST /api/sessions` now returns the full session object instead of just the ID.
FIX404 fallback handler: Unknown API routes now return JSON `{"error": "not found"}` instead of empty 404.
CHORECI scripts use POSIX grep: Replaced all `rg` (ripgrep) invocations with standard `grep -E`/`grep -qE` in CI scripts for broader runner compatibility.
CHOREWindows compilation: Added conditional `allow(unused_mut)` for platform-gated mutation in security audit command.

v0.8.0

Security Hardening & More2026-02-26

Security: 17 changes. Fixed: 22 changes. Added: 16 changes. Changed: 4 changes. Key changes: CORS hardening: Removed wildcard `Access-Control-Allow-Origin: *` fallback when no API key is configured; CORS now always restricts to the configured bind address origin. Wallet key zeroing: Decrypted API keys in the keystore and child agent wallet secrets are now wrapped in `Zeroizing<String>` so key material is zeroed on drop. Telegram invalid-token resilience: Telegram `404/401` poll failures are now classified as likely invalid/revoked bot-token errors with explicit repair guidance and adaptive backoff to reduce noisy tight-loop logging. Subagent runtime activation sync: Taskable subagents are now auto-started at boot and kept in sync with create/update/toggle/delete operations, fixing the `enabled > 0, running = 0` stall where configured subagents stayed idle.

Highlights

  • CORS hardening: Removed wildcard `Access-Control-Allow-Origin: *` fallback when no API key is configured; CORS now always restricts to the configured bind address origin.
  • Wallet key zeroing: Decrypted API keys in the keystore and child agent wallet secrets are now wrapped in `Zeroizing<String>` so key material is zeroed on drop.
  • WalletFile Debug redaction: `WalletFile` no longer derives `Debug`; a manual impl redacts `private_key_hex` to prevent accidental key leakage in logs or panics.
  • Plaintext wallet detection: Loading an unencrypted wallet file now emits a `SECURITY` warning at `warn!` level instead of silently succeeding.
  • Webhook signature enforcement: WhatsApp webhook verification now rejects requests with an error when `app_secret` is unconfigured, instead of silently skipping verification.
  • OAuth token persistence errors surfaced: `OAuthManager::persist()` now returns `Result<()>` and callers log failures at `error!` level instead of silently swallowing write errors.
  • Skill catalog path traversal prevention: Skill download filenames from remote registries are now validated and canonicalized to prevent `../` path traversal.
  • API key URL encoding: The `query:` auth mode now percent-encodes API keys before appending to URLs, preventing malformed requests and log leakage.
FIXCORS hardening: Removed wildcard `Access-Control-Allow-Origin: *` fallback when no API key is configured; CORS now always restricts to the configured bind address origin.
FIXWallet key zeroing: Decrypted API keys in the keystore and child agent wallet secrets are now wrapped in `Zeroizing<String>` so key material is zeroed on drop.
FIXWalletFile Debug redaction: `WalletFile` no longer derives `Debug`; a manual impl redacts `private_key_hex` to prevent accidental key leakage in logs or panics.
FIXPlaintext wallet detection: Loading an unencrypted wallet file now emits a `SECURITY` warning at `warn!` level instead of silently succeeding.
FIXWebhook signature enforcement: WhatsApp webhook verification now rejects requests with an error when `app_secret` is unconfigured, instead of silently skipping verification.
FIXOAuth token persistence errors surfaced: `OAuthManager::persist()` now returns `Result<()>` and callers log failures at `error!` level instead of silently swallowing write errors.
FIXSkill catalog path traversal prevention: Skill download filenames from remote registries are now validated and canonicalized to prevent `../` path traversal.
FIXAPI key URL encoding: The `query:` auth mode now percent-encodes API keys before appending to URLs, preventing malformed requests and log leakage.
FIXScript runner absolute path rejection: `resolve_script_path` now unconditionally rejects absolute paths instead of accepting them.
FIXScript file permission check: Script runner validates that script files are not world-writable on Unix before execution.
FIXSubagent name validation: Subagent names are now restricted to max 128 characters, alphanumeric + hyphens + underscores only.
FIXPlugin name/version validation: Plugin manifest validation now enforces character restrictions on plugin names and versions matching tool name rules.
FIXAudit log key redaction: Keystore audit log entries now redact key names to first 3 characters instead of logging full key identifiers.
FIXx402 recipient address validation: Payment authorization now validates that recipient addresses match Ethereum address format (0x + 40 hex chars).
FIXJSON merge depth limit: `update_config` recursive merge is now bounded to 10 levels of nesting to prevent stack overflow.
FIXError message sanitization: `sanitize_error_message` now strips content after common sensitive prefixes (file paths, SQLite errors, stack traces).
FIXDecided-by field sanitization: Approval decision `decided_by` field is now limited to 256 characters with control characters stripped.
FIXTelegram invalid-token resilience: Telegram `404/401` poll failures are now classified as likely invalid/revoked bot-token errors with explicit repair guidance and adaptive backoff to reduce noisy tight-loop logging.
FIXSubagent runtime activation sync: Taskable subagents are now auto-started at boot and kept in sync with create/update/toggle/delete operations, fixing the `enabled > 0, running = 0` stall where configured subagents stayed idle.
FIXFTS duplicate row accumulation: `store_semantic` and `store_working` now delete existing FTS entries before re-inserting, preventing unbounded duplicate growth in `memory_fts` on upserts.
FIXSSE stream UTF-8 corruption: `SseChunkStream` now uses proper incremental UTF-8 decoding instead of `from_utf8_lossy`, preserving multi-byte characters split across HTTP chunks.
FIXSSE buffer unbounded growth: SSE chunk stream buffer is now capped at 10 MB to prevent unbounded memory growth from long SSE lines.
FIXHeartbeat interval recovery: Heartbeat daemon interval now recovers to the original configured value when the survival tier returns to Normal, instead of permanently remaining at the degraded rate.
FIXAgentCardRefresh task activation: `HeartbeatTask::AgentCardRefresh` is now included in `default_tasks()` instead of being a dead variant.
FIXHippocampus identifier consistency: Table name validation in `create_agent_table` no longer allows hyphens, matching `validate_identifier` behavior.
FIXNegative hours SQL comment injection: `query_transactions` now clamps `hours` to positive values, preventing negative values from producing SQL comments.
FIXPRAGMA identifier quoting: `has_column` now quotes table names in `PRAGMA table_info` statements.
FIXCron lease identity verification: `release_lease` now requires the `lease_holder` parameter and verifies ownership before releasing.
FIXCoverage gate alignment: Local `justfile` coverage threshold now matches CI at 80% minimum.
FIX`just run-release` binary name: Fixed reference from `roboticus-server` to `roboticus`.
FIXSmoke test default port: `run-smoke.sh` default port corrected from 8787 to 18789.
FIXCORS fallback logging: Invalid CORS origin parse now logs a warning and falls back to `127.0.0.1` loopback instead of silently becoming wildcard `*`.
FIXCrypto function error propagation: `derive_key`, `encrypt_wallet_data` in wallet now return `Result` instead of panicking with `expect`.
FIXCapacityTracker mutex resilience: All `expect("mutex poisoned")` calls replaced with `unwrap_or_else(|e| e.into_inner())` for graceful recovery.
FIXRate limit / approval mutex resilience: Same mutex poison recovery applied to policy engine and approval manager.
FIXCron lease/run error logging: `acquire_lease`, `record_run`, and `release_lease` errors are now logged at `warn` level instead of silently discarded.
FIXInterval expression UTF-8 safety: `parse_interval_expr_to_ms` now uses `char_indices()` for correct byte-offset slicing of multi-byte characters.
FIXTOML serialization error propagation: `generate_operator_toml` and `generate_directives_toml` now return `Result<String>` instead of silently returning empty strings.
FIXFloating-point tier threshold: `SurvivalTier::from_balance` uses 0.999 epsilon for the `hours_below_zero` check to handle floating-point rounding.
FEATv0.8.0 zero-regression release gate: Added canonical `just test-v080-go-live` orchestration and release-blocking CI/release jobs for workspace tests, integration/regression batteries, bounded soak/fuzz checks, CLI+web UAT smoke, and release-doc/provenance consistency checks.
FEATWASM execution timeout enforcement: WASM plugin execution now tracks elapsed time against the configured `execution_timeout_ms` and logs warnings when exceeded.
FEATWASM memory bounds validation: WASM input writes check memory size before writing; output reads validate `ptr + len` against module memory bounds.
FEATBrowser evaluate length limit: `BrowserAction::Evaluate` rejects expressions exceeding 100,000 characters.
FEATEmail body size limit: Email adapter truncates message bodies exceeding 1 MB.
FEATA2a session establishment check: Added `is_established()` method and documentation for session key typestate.
FEATA2a rate window eviction: Rate limit windows now evict stale entries (>1 hour idle) when exceeding 1,000 tracked peers.
FEATInboundMessage platform sanitization: Added `sanitize_platform()` to strip control characters and enforce 64-char limit.
FEATYieldEngine field encapsulation: All fields made private with getter methods.
FEATTreasuryPolicy field encapsulation: All fields made private with constructor and getter methods.
FEATZero-amount deposit/withdraw rejection: `YieldEngine::deposit()` and `withdraw()` now reject amounts <= 0.
FEATPlugin registry unregister: Added `unregister()` method to fully remove plugin entries.
FEATScript shebang validation: Extensionless script files now require a recognized shebang line.
FEATDocker HEALTHCHECK: Dockerfile now includes a health check against `/api/health`.
FEATDocker build reproducibility: Dockerfile now uses `--locked`, MSRV-pinned Rust image, and dependency layer caching.
FEATRelease CI supply-chain hardening: `cross` installation pinned to versioned release instead of git HEAD.
CHOREWhatsApp client initialization: `reqwest::Client` builder now uses `expect()` instead of `unwrap_or_default()` to surface TLS initialization failures.
CHORECDP client initialization: Same `expect()` change applied to browser CDP HTTP client.
CHORESemantic search scan limit: `search_similar` now includes `LIMIT 10000` to bound memory usage pending AnnIndex integration.
CHORESemanticCache thread safety documentation: Documented `&mut self` requirement and external synchronization expectations.

v0.7.1

Hotfixes & Reliability2026-02-25

Fixed: 6 changes. Key changes: Windows daemon startup and binary update reliability fixes, dashboard render boundary hardening, and loopback-proxy migration safeguards with explicit deprecation guidance for v0.8.0 removal.

Highlights

  • Windows daemon startup reliability: Replaced the broken `sc.exe` service launch path with a detached user-process daemon flow.
  • Windows binary update guardrail: `roboticus update binary` now blocks in-process self-update on Windows and prints safe manual upgrade steps.
  • Dashboard JS bleed-through fix: Dashboard rendering is clipped to the canonical HTML document boundary.
  • In-process provider routing metadata: `/api/models/available` reports in-process proxy mode and provider diagnostics for clearer operator visibility.
  • Loopback proxy deprecation guidance: `0.7.x` warns that `127.0.0.1:8788/<provider>` is deprecated and will be removed in `v0.8.0`.
FIXWindows daemon startup reliability: Replaced the broken `sc.exe` service launch path with a detached user-process daemon flow.
FIXWindows binary update guardrail: `roboticus update binary` now blocks in-process self-update on Windows and prints safe manual upgrade steps.
FIXDashboard JS bleed-through fix: Dashboard rendering is clipped to the canonical HTML document boundary.
FIXIn-process provider routing metadata: `/api/models/available` reports in-process proxy mode and provider diagnostics for clearer operator visibility.
DOCSLoopback proxy deprecation guidance: `0.7.x` warns that `127.0.0.1:8788/<provider>` is deprecated and will be removed in `v0.8.0`.

v0.7.0

New Features2026-02-25

Added: 4 changes. Changed: 3 changes. Key changes: Subagent contract enforcement: Added explicit `subagent` vs `model-proxy` role validation, fixed-skills persistence/validation, and strict rejection of personality payloads for taskable subagents. Model-selection forensics pipeline: Added persistent `model_selection_events` storage, turn-linked forensics APIs (`GET /api/turns/{id}/model-selection`, `GET /api/models/selections`), and live dashboard views for candidate evaluation details. Roster and status semantics: `/api/roster`, `/api/agent/status`, and dashboard agent views now distinguish taskable subagents from model proxies and report taskable counts with clearer operator-facing terminology. Subagent model assignment options: Added support for `auto` (router-controlled) and `commander` (primary-agent-assigned) model modes for taskable subagents, including runtime model resolution behavior.

Highlights

  • Subagent contract enforcement: Added explicit `subagent` vs `model-proxy` role validation, fixed-skills persistence/validation, and strict rejection of personality payloads for taskable subagents.
  • Model-selection forensics pipeline: Added persistent `model_selection_events` storage, turn-linked forensics APIs (`GET /api/turns/{id}/model-selection`, `GET /api/models/selections`), and live dashboard views for candidate evaluation details.
  • Streaming turn traceability: `POST /api/agent/message/stream` now emits stable `turn_id` values from stream start through completion and records per-turn model-selection audits for streamed responses.
  • Subagent ubiquitous-language architecture doc: Added `docs/architecture/subagent-ubiquitous-language.md` with canonical terminology, gap audit, and dataflow diagrams.
  • Roster and status semantics: `/api/roster`, `/api/agent/status`, and dashboard agent views now distinguish taskable subagents from model proxies and report taskable counts with clearer operator-facing terminology.
  • Subagent model assignment options: Added support for `auto` (router-controlled) and `commander` (primary-agent-assigned) model modes for taskable subagents, including runtime model resolution behavior.
  • Context forensics UX: Context Explorer now supports live stream-turn handoff and direct forensic drill-down using active `turn_id` metadata.
FEATSubagent contract enforcement: Added explicit `subagent` vs `model-proxy` role validation, fixed-skills persistence/validation, and strict rejection of personality payloads for taskable subagents.
FEATModel-selection forensics pipeline: Added persistent `model_selection_events` storage, turn-linked forensics APIs (`GET /api/turns/{id}/model-selection`, `GET /api/models/selections`), and live dashboard views for candidate evaluation details.
FEATStreaming turn traceability: `POST /api/agent/message/stream` now emits stable `turn_id` values from stream start through completion and records per-turn model-selection audits for streamed responses.
FEATSubagent ubiquitous-language architecture doc: Added `docs/architecture/subagent-ubiquitous-language.md` with canonical terminology, gap audit, and dataflow diagrams.
CHORERoster and status semantics: `/api/roster`, `/api/agent/status`, and dashboard agent views now distinguish taskable subagents from model proxies and report taskable counts with clearer operator-facing terminology.
CHORESubagent model assignment options: Added support for `auto` (router-controlled) and `commander` (primary-agent-assigned) model modes for taskable subagents, including runtime model resolution behavior.
CHOREContext forensics UX: Context Explorer now supports live stream-turn handoff and direct forensic drill-down using active `turn_id` metadata.

v0.6.1

Bug Fixes & Stability2026-02-24

Fixed: 3 changes. Key changes: Release integrity follow-up: Merged post-tag regression fixes from the 0.6.0 release branch into `develop`, including web peer-scope identity validation, dashboard WebSocket token encoding, and release-gate compile/test stabilization. Session creation stability: Restored explicit default agent scope behavior in DB session creation paths to avoid `500` failures in session lifecycle APIs/tests.

Highlights

  • Release integrity follow-up: Merged post-tag regression fixes from the 0.6.0 release branch into `develop`, including web peer-scope identity validation, dashboard WebSocket token encoding, and release-gate compile/test stabilization.
  • Session creation stability: Restored explicit default agent scope behavior in DB session creation paths to avoid `500` failures in session lifecycle APIs/tests.
  • Routing test alignment: Updated router integration expectations to reflect current fallback behavior when primary providers are breaker-blocked.
FIXRelease integrity follow-up: Merged post-tag regression fixes from the 0.6.0 release branch into `develop`, including web peer-scope identity validation, dashboard WebSocket token encoding, and release-gate compile/test stabilization.
FIXSession creation stability: Restored explicit default agent scope behavior in DB session creation paths to avoid `500` failures in session lifecycle APIs/tests.
FIXRouting test alignment: Updated router integration expectations to reflect current fallback behavior when primary providers are breaker-blocked.

v0.6.0

New Features2026-02-24

Added: 4 changes. Changed: 5 changes. Key changes: Capacity headroom telemetry: New `GET /api/stats/capacity` endpoint exposes per-provider headroom, utilization, and sustained-pressure flags for operator visibility. Capacity-aware circuit preemption: Circuit breakers now accept soft capacity pressure signals and expose preemptive `half_open` state before hard failure trips. Routing quality now capacity-weighted: `select_for_complexity()` scores candidates by model quality and provider headroom, rather than binary near-capacity fallback behavior. Inference feedback loop now records capacity usage: both non-stream and stream response paths record provider token/request usage and update capacity pressure signals.

Highlights

  • Capacity headroom telemetry: New `GET /api/stats/capacity` endpoint exposes per-provider headroom, utilization, and sustained-pressure flags for operator visibility.
  • Capacity-aware circuit preemption: Circuit breakers now accept soft capacity pressure signals and expose preemptive `half_open` state before hard failure trips.
  • Session scope backfill migration: Added `012_session_scope_backfill_unique.sql` to normalize legacy sessions to explicit scope and enforce unique active scoped sessions.
  • Safe markdown rendering in dashboard sessions: Session chat and Context Explorer now render markdown with strict URL sanitization and no raw HTML execution.
  • Routing quality now capacity-weighted: `select_for_complexity()` scores candidates by model quality and provider headroom, rather than binary near-capacity fallback behavior.
  • Inference feedback loop now records capacity usage: both non-stream and stream response paths record provider token/request usage and update capacity pressure signals.
  • Session scoping defaults to explicit agent scope: `find_or_create()` now uses `agent` scope by default and channel/web paths pass scoped keys for peer/group isolation.
  • Channel session affinity: Channel dedup and session selection now use resolved chat/channel identity instead of platform-only sender affinity.
FEATCapacity headroom telemetry: New `GET /api/stats/capacity` endpoint exposes per-provider headroom, utilization, and sustained-pressure flags for operator visibility.
FEATCapacity-aware circuit preemption: Circuit breakers now accept soft capacity pressure signals and expose preemptive `half_open` state before hard failure trips.
FEATSession scope backfill migration: Added `012_session_scope_backfill_unique.sql` to normalize legacy sessions to explicit scope and enforce unique active scoped sessions.
FEATSafe markdown rendering in dashboard sessions: Session chat and Context Explorer now render markdown with strict URL sanitization and no raw HTML execution.
CHORERouting quality now capacity-weighted: `select_for_complexity()` scores candidates by model quality and provider headroom, rather than binary near-capacity fallback behavior.
CHOREInference feedback loop now records capacity usage: both non-stream and stream response paths record provider token/request usage and update capacity pressure signals.
CHORESession scoping defaults to explicit agent scope: `find_or_create()` now uses `agent` scope by default and channel/web paths pass scoped keys for peer/group isolation.
CHOREChannel session affinity: Channel dedup and session selection now use resolved chat/channel identity instead of platform-only sender affinity.
CHOREHeartbeat now runs SessionGovernor: stale sessions are expired with compaction draft capture; optional hourly rotation is triggered when `session.reset_schedule` is configured.

v0.5.0

New Features (25 changes)2026-02-23

Added: 18 changes. Changed: 7 changes. Key changes: Addressability Filter: Composable filter chain for group chat addressability detection. Agent only responds when mentioned by name, replied to, or in a DM. Configurable via `[addressability]` config section with alias names support. Response Transform Pipeline: Three-stage pipeline applied to all LLM responses -- `ReasoningExtractor` (captures `<think>` blocks), `FormatNormalizer` (whitespace/fence cleanup), `ContentGuard` (injection defense). Replaces the previous inline `scan_output` approach. All 10 crate READMEs updated to v0.5.0 with expanded descriptions and key types. All 10 `lib.rs` files now have `//!` crate-level doc comments.

Highlights

  • Addressability Filter: Composable filter chain for group chat addressability detection. Agent only responds when mentioned by name, replied to, or in a DM. Configurable via `[addressability]` config section with alias names support.
  • Response Transform Pipeline: Three-stage pipeline applied to all LLM responses -- `ReasoningExtractor` (captures `<think>` blocks), `FormatNormalizer` (whitespace/fence cleanup), `ContentGuard` (injection defense). Replaces the previous inline `scan_output` approach.
  • Flexible Network Binding: Interface-based binding (`bind_interface`), optional TLS via `axum-server` with rustls, and `advertise_url` for agent card generation.
  • Approval Workflow Loop Integration: Agent pauses on gated tool calls, publishes `pending_approval` events via WebSocket, and resumes after admin approve/deny. Dashboard "Approvals" panel with real-time updates.
  • Browser as Agent Tool: `BrowserTool` adapter wrapping the 12-action `roboticus-browser` crate, registered in `ToolRegistry`. Tool schemas injected into system prompt so the LLM can request browser actions.
  • Context Observatory: Full turn inspector and analytics suite:
  • Turn recording with `context_snapshots` table capturing token allocation, memory tier breakdown, complexity level, and model for every LLM call
  • Turn & Context API: `GET /api/sessions/{id}/turns`, `GET /api/turns/{id}`, `GET /api/turns/{id}/context`, `GET /api/turns/{id}/tools`
FEATAddressability Filter: Composable filter chain for group chat addressability detection. Agent only responds when mentioned by name, replied to, or in a DM. Configurable via `[addressability]` config section with alias names support.
FEATResponse Transform Pipeline: Three-stage pipeline applied to all LLM responses -- `ReasoningExtractor` (captures `<think>` blocks), `FormatNormalizer` (whitespace/fence cleanup), `ContentGuard` (injection defense). Replaces the previous inline `scan_output` approach.
FEATFlexible Network Binding: Interface-based binding (`bind_interface`), optional TLS via `axum-server` with rustls, and `advertise_url` for agent card generation.
FEATApproval Workflow Loop Integration: Agent pauses on gated tool calls, publishes `pending_approval` events via WebSocket, and resumes after admin approve/deny. Dashboard "Approvals" panel with real-time updates.
FEATBrowser as Agent Tool: `BrowserTool` adapter wrapping the 12-action `roboticus-browser` crate, registered in `ToolRegistry`. Tool schemas injected into system prompt so the LLM can request browser actions.
FEATContext Observatory: Full turn inspector and analytics suite:
FEATTurn recording with `context_snapshots` table capturing token allocation, memory tier breakdown, complexity level, and model for every LLM call
FEATTurn & Context API: `GET /api/sessions/{id}/turns`, `GET /api/turns/{id}`, `GET /api/turns/{id}/context`, `GET /api/turns/{id}/tools`
FEATDashboard per-message context expansion (token allocation bar, memory breakdown, reasoning trace, tool calls)
FEATContext Explorer tab with session selector, turn timeline, and aggregate charts
FEATHeuristic context analyzer with 12 per-turn rules and 10 session-aggregate rules across Budget, Memory, Prompt, Tools, Cost, and Quality categories
FEATLLM-powered deep analysis stub for on-demand qualitative context evaluation
FEATPrompt efficiency metrics per model: output density, budget utilization, memory ROI, cache hit rate, context pressure, cost attribution
FEATEfficiency dashboard with model comparison cards, time series charts, period selector, and auto-generated cost optimization tips
FEATOutcome grading: 1-5 star ratings on assistant responses via `turn_feedback` table, with quality-adjusted metrics (cost per quality point, quality by complexity, memory impact analysis)
FEATBehavioral recommendations engine: ~14 heuristic rules across 7 categories (query crafting, model selection, session management, memory leverage, cost optimization, tool usage, configuration) with evidence and estimated impact
FEATStreaming LLM Responses: `SseChunkStream` adapter for token-by-token streaming. `POST /api/agent/message/stream` SSE endpoint. WebSocket forwarding via EventBus. Dashboard incremental rendering with typing indicator.
FEATNew reference documents: `docs/CONFIGURATION.md`, `docs/CLI.md`, `docs/API.md`, `docs/DEPLOYMENT.md`, `docs/ENV.md`
CHOREAll 10 crate READMEs updated to v0.5.0 with expanded descriptions and key types
CHOREAll 10 `lib.rs` files now have `//!` crate-level doc comments
CHORE10 new dataflow diagrams added to `roboticus-dataflow.md` (approval, browser, context, transform, streaming, addressability, observatory, plugin SDK, OAuth, channel lifecycle)
CHORE6 new sequence diagrams added to `roboticus-sequences.md` (approval, streaming, turn recording, grading, TLS, CDP)
CHOREAll 6 C4 component diagrams updated with ~40 previously undocumented modules
CHOREDocumentation standards added to CONTRIBUTING.md
CHORE`cargo doc` CI gate added with `-D warnings` to prevent future documentation drift

v0.4.3

New Features & More2026-02-23

Added: 6 changes. Fixed: 3 changes. Changed: 2 changes. Key changes: Slash commands for agent chat: `/model`, `/models`, `/breaker`, `/retry` for runtime LLM control. Runtime model override via `/model set <model>` — temporarily forces a specific model, bypassing routing. Credit/billing errors now permanently trip the circuit breaker (no auto-recovery to HalfOpen) — providers with exhausted credits are never probed again until explicitly reset via `/breaker reset`. Dashboard "Save to keystore" button now sends `Content-Type: application/json` header — previously failed with "Expected request with 'Content-Type: application/json'".

Highlights

  • Slash commands for agent chat: `/model`, `/models`, `/breaker`, `/retry` for runtime LLM control
  • Runtime model override via `/model set <model>` — temporarily forces a specific model, bypassing routing
  • Circuit breaker status and reset via `/breaker` and `/breaker reset [provider]` slash commands
  • Breaker-aware model routing — `select_for_complexity` and `select_cheapest_qualified` now skip providers with tripped circuit breakers
  • Pre-flight API key check in `infer_with_fallback` — cloud providers with no configured key are skipped before sending a doomed request
  • Dashboard settings inputs show a dimmed "none" placeholder instead of literal "null" for empty fields
  • Credit/billing errors now permanently trip the circuit breaker (no auto-recovery to HalfOpen) — providers with exhausted credits are never probed again until explicitly reset via `/breaker reset`
  • Dashboard "Save to keystore" button now sends `Content-Type: application/json` header — previously failed with "Expected request with 'Content-Type: application/json'"
FEATSlash commands for agent chat: `/model`, `/models`, `/breaker`, `/retry` for runtime LLM control
FEATRuntime model override via `/model set <model>` — temporarily forces a specific model, bypassing routing
FEATCircuit breaker status and reset via `/breaker` and `/breaker reset [provider]` slash commands
FEATBreaker-aware model routing — `select_for_complexity` and `select_cheapest_qualified` now skip providers with tripped circuit breakers
FEATPre-flight API key check in `infer_with_fallback` — cloud providers with no configured key are skipped before sending a doomed request
FEATDashboard settings inputs show a dimmed "none" placeholder instead of literal "null" for empty fields
FIXCredit/billing errors now permanently trip the circuit breaker (no auto-recovery to HalfOpen) — providers with exhausted credits are never probed again until explicitly reset via `/breaker reset`
FIXDashboard "Save to keystore" button now sends `Content-Type: application/json` header — previously failed with "Expected request with 'Content-Type: application/json'"
FIXSettings form no longer renders `"null"` as a literal value in input fields; empty fields display a styled placeholder and save as `null`
CHOREMerged "Roster" and "Agents" into a single "Agents" page with tabbed Roster/List views
CHORERemoved CLI typing sound effects (`start_typing_sound` / `SoundHandle`) from banner rendering

v0.4.2

Bug Fixes & Stability2026-02-23

Fixed: 3 changes. Key changes: `roboticus daemon start` now verifies the service is actually running after `launchctl load` — previously reported "Daemon started" even when the service crashed immediately. `roboticus daemon install` resolves the config path to absolute before embedding in the plist — previously used the relative path which launchd couldn't resolve.

Highlights

  • `roboticus daemon start` now verifies the service is actually running after `launchctl load` — previously reported "Daemon started" even when the service crashed immediately
  • `roboticus daemon install` resolves the config path to absolute before embedding in the plist — previously used the relative path which launchd couldn't resolve
  • Captures launchctl stderr and checks `LastExitStatus` / PID to give actionable error messages on daemon start failure
FIX`roboticus daemon start` now verifies the service is actually running after `launchctl load` — previously reported "Daemon started" even when the service crashed immediately
FIX`roboticus daemon install` resolves the config path to absolute before embedding in the plist — previously used the relative path which launchd couldn't resolve
FIXCaptures launchctl stderr and checks `LastExitStatus` / PID to give actionable error messages on daemon start failure

v0.4.1

Security Hardening & More2026-02-23

Added: 5 changes. Fixed: 7 changes. Security: 4 changes. Key changes: `roboticus daemon start|stop|restart` subcommands for full daemon lifecycle management. Interactive prompt after `roboticus daemon install` asking whether to start immediately. Replaced stale `[providers.local]` (localhost:8080) with `[providers.moonshot]` in bundled and registry provider configs. Added `moonshot/kimi-k2.5` to dashboard known-models list for settings autocomplete.

Highlights

  • `roboticus daemon start|stop|restart` subcommands for full daemon lifecycle management
  • Interactive prompt after `roboticus daemon install` asking whether to start immediately
  • `--start` flag on `roboticus daemon install` for non-interactive use
  • Dashboard keystore management: save/remove provider API keys from the settings page
  • Session nicknames in dashboard sessions table with click-to-copy session ID
  • Replaced stale `[providers.local]` (localhost:8080) with `[providers.moonshot]` in bundled and registry provider configs
  • Added `moonshot/kimi-k2.5` to dashboard known-models list for settings autocomplete
  • `roboticus daemon install` now actually offers to load the service (previously only wrote the plist/unit file)
FEAT`roboticus daemon start|stop|restart` subcommands for full daemon lifecycle management
FEATInteractive prompt after `roboticus daemon install` asking whether to start immediately
FEAT`--start` flag on `roboticus daemon install` for non-interactive use
FEATDashboard keystore management: save/remove provider API keys from the settings page
FEATSession nicknames in dashboard sessions table with click-to-copy session ID
FIXReplaced stale `[providers.local]` (localhost:8080) with `[providers.moonshot]` in bundled and registry provider configs
FIXAdded `moonshot/kimi-k2.5` to dashboard known-models list for settings autocomplete
FIX`roboticus daemon install` now actually offers to load the service (previously only wrote the plist/unit file)
FIX`roboticus daemon uninstall` now stops the running service before removing the file
FIX`roboticus daemon status` distinguishes between "not installed" and "installed but not running"
FIXRegistry URL restored to correct `roboticus.ai/registry` path (not subdomain)
FIXEmpty env vars no longer falsely reported as "configured" in key status checks
FIX`delete_provider_key` endpoint now validates provider exists before allowing keystore deletion
FIXUnified key resolution via `KeySource` enum eliminates 3 duplicated cascade implementations
FIX`resolve_provider_key` returns `Option<String>` instead of silently sending empty auth headers
FIXReplace secret-looking test placeholders to prevent false GitGuardian alerts

v0.4.0

New Features & More2026-02-23

Added: 10 changes. Changed: 5 changes. Fixed: 2 changes. Key changes: Signal channel adapter backed by signal-cli JSON-RPC daemon (`roboticus-channels::signal`). Unified thinking indicator (🤖🧠…) for all chat channels (Telegram, WhatsApp, Discord, Signal). `thinking_threshold_seconds` moved from per-channel (`TelegramConfig`) to `ChannelsConfig` level. Channel message processing is now platform-agnostic via `send_typing_indicator` / `send_thinking_indicator` helpers.

Highlights

  • Signal channel adapter backed by signal-cli JSON-RPC daemon (`roboticus-channels::signal`)
  • Unified thinking indicator (🤖🧠…) for all chat channels (Telegram, WhatsApp, Discord, Signal)
  • Configurable `thinking_threshold_seconds` on `[channels]` — estimated latency gate for thinking indicator (default: 30s)
  • `send_typing` and `send_ephemeral` on WhatsApp and Discord adapters
  • Latency estimator based on model tier, input length, and circuit-breaker state
  • LLM fallback chain: `infer_with_fallback` helper retries across configured providers on transient errors
  • Permanent error detection in delivery queue — 403/401/400 and "bot blocked" errors dead-letter immediately
  • Config auto-discovery: `roboticus start` checks `~/.roboticus/roboticus.toml` when no `--config` flag is given
FEATSignal channel adapter backed by signal-cli JSON-RPC daemon (`roboticus-channels::signal`)
FEATUnified thinking indicator (🤖🧠…) for all chat channels (Telegram, WhatsApp, Discord, Signal)
FEATConfigurable `thinking_threshold_seconds` on `[channels]` — estimated latency gate for thinking indicator (default: 30s)
FEAT`send_typing` and `send_ephemeral` on WhatsApp and Discord adapters
FEATLatency estimator based on model tier, input length, and circuit-breaker state
FEATLLM fallback chain: `infer_with_fallback` helper retries across configured providers on transient errors
FEATPermanent error detection in delivery queue — 403/401/400 and "bot blocked" errors dead-letter immediately
FEATConfig auto-discovery: `roboticus start` checks `~/.roboticus/roboticus.toml` when no `--config` flag is given
FEATObsidian vault integration module with read, search, and write tools
FEATGitHub Actions release workflow for cross-platform binaries and crates.io publishing
CHORE`thinking_threshold_seconds` moved from per-channel (`TelegramConfig`) to `ChannelsConfig` level
CHOREChannel message processing is now platform-agnostic via `send_typing_indicator` / `send_thinking_indicator` helpers
CHOREDelivery queue `mark_failed` checks for permanent errors before scheduling retries
CHOREChannel router `send_to` and `drain_retry_queue` skip retry enqueue for permanent errors
CHORECircuit breaker test updated to reflect fallback-first behavior
FIXLLM inference no longer returns a static error when the primary provider is down — falls through to configured fallbacks
FIXTelegram bot no longer retries messages to chats it was removed from (permanent error dead-lettering)

v0.3.0

Security Hardening & More2026-02-23

Security: 8 changes. Fixed: 11 changes. Changed: 10 changes. Added: 1 change. Key changes: Plugin sandbox: validate tool names against allowlist; reject path-traversal payloads; add `shutdown_all` for graceful teardown. Browser restrictions: block `file://`, `javascript:`, `data:` URI schemes in CDP navigation; harden Chrome launch flags. Telegram adapter now processes all updates in a batch, not just the first. Cron worker dispatches jobs instead of unconditionally marking success.

Highlights

  • Plugin sandbox: validate tool names against allowlist; reject path-traversal payloads; add `shutdown_all` for graceful teardown
  • Browser restrictions: block `file://`, `javascript:`, `data:` URI schemes in CDP navigation; harden Chrome launch flags
  • Session role validation: reject messages with roles outside `{user, assistant, system, tool}`
  • Channel message authority: trusted sender IDs config for elevated `ChannelAuthority`
  • WhatsApp webhook signature verification via HMAC-SHA256
  • Docker: run as non-root `roboticus` user
  • Wallet: encrypt private keys with machine-derived passphrase; never store plaintext
  • API key `#[serde(skip_serializing)]` prevents accidental serialization leakage
FIXPlugin sandbox: validate tool names against allowlist; reject path-traversal payloads; add `shutdown_all` for graceful teardown
FIXBrowser restrictions: block `file://`, `javascript:`, `data:` URI schemes in CDP navigation; harden Chrome launch flags
FIXSession role validation: reject messages with roles outside `{user, assistant, system, tool}`
FIXChannel message authority: trusted sender IDs config for elevated `ChannelAuthority`
FIXWhatsApp webhook signature verification via HMAC-SHA256
FIXDocker: run as non-root `roboticus` user
FIXWallet: encrypt private keys with machine-derived passphrase; never store plaintext
FIXAPI key `#[serde(skip_serializing)]` prevents accidental serialization leakage
FIXTelegram adapter now processes all updates in a batch, not just the first
FIXCron worker dispatches jobs instead of unconditionally marking success
FIXCron expressions use the `cron` crate for full syntax support (ranges, lists, steps)
FIXPer-IP rate-limit HashMap evicted on window reset, preventing unbounded growth
FIXInterview sessions capped at 100 with 1-hour TTL; expired sessions evicted
FIX`Cargo.lock` committed; CI builds use `--locked` for reproducible builds
FIXGraceful shutdown handler (SIGINT + SIGTERM) via `with_graceful_shutdown()`
FIXDuplicate migration version numbers renumbered to unique sequential IDs
FIXMigrations wrapped in transactions for atomicity
FIXSQL `LIKE` patterns escape user-supplied wildcards
FIXMemory query endpoints clamp limit to 1000
CHOREDeduplicated `Optional<T>` trait across 5 DB modules; use `rusqlite::OptionalExtension`
CHORE`SessionStatus` and `MessageRole` enums added for future type-safe migration
CHORERegex allocation in `decode_common_encodings` hoisted to static `LazyLock`
CHORESilent `.ok()` calls in `ingest_turn()` replaced with `tracing::warn!` logging
CHOREReusable `reqwest::Client` stored in `Wallet` for connection pooling
CHOREA2A sessions made private with TTL eviction and 256-session cap
CHOREPlugin registry releases lock before tool execution (`Arc<Mutex<Box<dyn Plugin>>>`)
CHORE`CdpSession::set_timeout` now functional (was a documented no-op)
CHOREDaemon logs written to `~/.roboticus/logs/` instead of world-readable `/tmp/`
CHOREDeduplicated `collect_string_values` across policy rules
FEATPre-commit hook for fast format checks (`hooks/pre-commit`)

v0.2.0

Alpha Release2026-02-23

Full roadmap implementation — 35 items across 7 phases. ReAct agent loop, RAG retrieval pipeline, embedding provider integration, ANN index, persistent semantic cache, sub-agent framework, and comprehensive bug fixes from code review.

Highlights

  • ReAct agent loop with idle/loop detection
  • 5-tier hybrid RAG retrieval (FTS5 + vector cosine)
  • Embedding provider integration (OpenAI, Ollama, Google)
  • HNSW approximate nearest neighbor index
  • Persistent semantic cache (SQLite-backed, auto-eviction)
  • Sub-agent framework with isolated tool registries
  • 22 code review issues resolved (6 critical, 12 high, 4 medium)
  • RwLock deadlock fix in circuit breaker path
  • UTF-8 safety, atomic OAuth persistence, poison recovery
FEATImplement full Roboticus roadmap (35 items across 7 phases)
FEATApplication layer — ReAct agent, RAG retrieval, sub-agents, full server wiring
FEATFoundation layer — embeddings, keystore, ANN index, cache persistence
FIXResolve RwLock deadlock in circuit breaker path
FIXResolve all 22 code review issues (6 CRITICAL, 12 HIGH, 4 MEDIUM)
FIXReplace all placeholder code with real implementations
FIXAuto-restart on port conflict during serve
FIXUpdate bootstrap sequence to 13 steps with cache-load step
FIXGoogle batch endpoint, parse error propagation, query auth in embedding
FIXBlocking read in async, UTF-8 safe chunking, dedup release on send failure
FIXChannel L4 filter, survival tier, dedup leaks, interview deadlock
FIXUTF-8 safety, atomic OAuth persist, poison recovery, embedding errors
FIXWire BOOT_6B node, remove OpenClaw refs, reorder roadmap sections
FIXLint errors from merge and update coverage baseline
DOCSUpdate architecture diagrams, roadmap, and crate READMEs
CHOREBump version to 0.2.0 for Roboticus alpha release

v0.1.0

New Features & More2026-02-22

Added: 5 changes. Changed: 1 change. Fixed: 1 change. Key changes: Initial Project Roboticus baseline for Roboticus. Multi-crate Rust workspace foundation (runtime crates + integration test crate). Prepared packaging/publish metadata for early release workflows. Early release stabilization fixes for binary packaging, startup wiring, and quality gates.

Highlights

  • Initial Project Roboticus baseline for Roboticus.
  • Multi-crate Rust workspace foundation (runtime crates + integration test crate).
  • Core SQLite persistence layer with schema/migrations and operational defaults.
  • Early HTTP API, CLI surface, and embedded dashboard scaffolding.
  • Initial architecture and reference documentation set.
  • Prepared packaging/publish metadata for early release workflows.
  • Early release stabilization fixes for binary packaging, startup wiring, and quality gates.
FEATInitial Project Roboticus baseline for Roboticus.
FEATMulti-crate Rust workspace foundation (runtime crates + integration test crate).
FEATCore SQLite persistence layer with schema/migrations and operational defaults.
FEATEarly HTTP API, CLI surface, and embedded dashboard scaffolding.
FEATInitial architecture and reference documentation set.
CHOREPrepared packaging/publish metadata for early release workflows.
FIXEarly release stabilization fixes for binary packaging, startup wiring, and quality gates.