All notable changes to this repository are documented in this file.
The format is inspired by Keep a Changelog and follows milestone-based delivery evidence in specs/.
- wasmtime 25.0.3 → 36 across the workspace, clearing RUSTSEC-2026-0096 (CVSS 9.0, aarch64 guest heap miscompile). No API breaks on the
Config/Engine/Module/Store/Linker/Memorysurface used bytau-runtime::wasm_sandbox_runtime. See docs/solutions/patterns/wasmtime-25-to-36-upgrade-no-api-breaks.md. - Hardened
self_modification_runtime::cleanup_self_mod_worktree: canonicalize-with-parent-fallback containment check, proposal-id ASCII allowlist with..rejection, segment-basedclassify_modification_target. See docs/solutions/patterns/self-modification-worktree-containment.md. - Exited the vulnerable
rustls-webpki 0.102.8transitive chain by switchingserenityfromrustls_backendtonative_tls_backend. Clears four advisories (RUSTSEC-2026-0049, -0098, -0099, -0104) locked in byserenity 0.12.5(latest crates.io release).tau-discord-runtimenow uses the OS TLS implementation (SecureTransport / Schannel / OpenSSL). No public-API impact; end-to-end tests green. Revisit when serenity upstream bumps its rustls dependency. - Added
.cargo/audit.tomlwith per-advisory ignore rationale for four non-exploitable unmaintained/unsound-transitive warnings (RUSTSEC-2025-0057fxhash, RUSTSEC-2024-0384instant, RUSTSEC-2024-0436paste, RUSTSEC-2026-0002lruvia ratatui).cargo auditnow reports zero vulnerabilities and zero warnings. Each entry carries the upstream path and review trigger so they are not silent.
tau-coding-agent::self_modification_tool::SelfModificationProposeTool—AgentToolimplementation making the dry-run pipeline invokable autonomously via the standard tool-call path. Gated by theTAU_AUTONOMOUS_SELF_MOD=1environment variable; refuses withreason_code: "autonomous_self_mod_disabled"when unset. Never applies changes — always dry-run. Six unit tests cover env-gate on/off/"0", invalid-arguments rejection, allowed-skill happy path, and source-target policy denial.tau-coding-agent::tools::register_builtin_toolsnow wrapstau_tools::tools::register_builtin_toolsand additionally registersSelfModificationProposeToolon every agent built through the coding-agent registry path (including the runtime inevents.rs). Fail-closed remains in effect via the env gate; the tool is visible-but-refused so the model observes a structured error rather than silently missing capability.ToolPolicy::self_modification_propose_enabled(defaults tofalse) — defense-in-depth registration gate on top of theTAU_AUTONOMOUS_SELF_MODruntime env gate. Whenfalse, the self-modification tool is not registered at all (model cannot see it); whentrue, the tool is advertised but still refuses to execute unless the env gate is also set. Two independent switches with distinct semantics: policy controls visibility, env controls invocability. Two new unit tests (unit_register_builtin_tools_omits_self_modification_propose_by_default,unit_register_builtin_tools_includes_self_modification_propose_when_enabled) pin the behavior.tau-coding-agent::self_modification_synthesis_tool::SelfModificationSynthesizeTool— the synthesis half of the autonomous self-modification pair. Takes a natural-language intent, calls the agent'sLlmClientwith a strict-JSON system prompt, validates the output (path traversal, absolute paths, ASCII allowlist, change_type enum, max-output-bytes), and returns a structured proposal{ target, change_type, rationale, proposed_diff, policy_projected }. The tool never applies changes and never invokes the dry-run pipeline — the LLM chooses whether to chain its output throughself_modification_propose. Four independent gates now protect the autonomous path: policy flag (visibility), env gate (invocability), synthesis-time output validation (parser), and the dry-run boundary on the propose tool. Nine unit tests cover happy path, path-traversal rejection, absolute-path rejection, invalid change_type, malformed JSON, LLM transport error, markdown-fenced output tolerance, empty-intent rejection, and env-gate refusal.ToolPolicy::self_modification_synthesize_enabled(defaults tofalse) — registration gate for the synthesis tool; paired withregister_self_modification_synthesiswhich takes theLlmClient+ model explicitly because synthesis needs them at construction time. Two registry unit tests pin the gate behavior (unit_register_self_modification_synthesis_omits_tool_by_default,unit_register_self_modification_synthesis_includes_tool_when_enabled).- Crate-level test-only
AUTONOMOUS_SELF_MOD_ENV_LOCKintau-coding-agent::lib— shared across every test module that mutates the env var, so parallel tests in different modules cannot interleave env mutations and observe a torn state. tau-coding-agent: new operator binaryself-mod-dry-runexercising the self-modification dry-run pipeline end-to-end. JSON-on-stdout contract;tracingon stderr viaTAU_SELF_MOD_LOG.tau-coding-agent::self_modification_pipelinemodule wiring validate → classify → policy → worktree → cleanup with structuredtracingevents. Previously the self-modification runtime had zero production call sites; now exposed via the operator bin and a minimaltau_coding_agentlibrary seam.- ADR: docs/adrs/0001-self-modification-dry-run-pipeline.md records the library-seam + standalone-bin decision.
- Integration test crates/tau-coding-agent/tests/self_mod_dry_run_bin.rs exercises the operator bin argv → JSON contract with three adversarial cases (allowed-skill, denied-source, hostile-proposal-id).
- Integration test crates/tau-coding-agent/tests/synthesize_then_propose_chain.rs — end-to-end composability check: fake
LlmClient→SelfModificationSynthesizeTool→SelfModificationProposeToolin one process. Covers (a) skill-target happy path flowing synthesis output unchanged into propose, and (b) source-target path where synthesis projectswould_be_blockedand propose correctly returns a structuredauto_apply_source_disableddenial. Closes the "each tool works in isolation but are they composable?" gap. tau-agent-core::agent_channel:tracinginstrumentation on message drops (subscriber-count tracking + structuredfrom_agent_id/message_typefields).
tau-coding-agent: dropped#![allow(dead_code)]fromself_modification_runtime; all public surface now has live callers.tau-coding-agent::self-mod-dry-run:tracingsubscriber emits to stderr (not stdout) and defaults to silent — preserves the stdout JSON contract for downstream consumers.tau-memory::runtime: extracteddefaults(serde default functions, 81 lines),normalize(scope/entry/relation/sqlite-int normalization pluscurrent_unix_timestamp_ms, 153 lines),file_store(theFileMemoryStorestruct + ~380-line impl block, 409 lines total),types(23 pub/pub(super) data types + their inherent/Default impls, 560 lines),tests(lifted the#[cfg(test)] mod testsblock verbatim, 2487 lines), and then the tests module itself into per-feature sibling files underruntime/tests/:lifecycle.rs(spec_2455/2460, 621 lines),relations.rs(spec_2592 + normalize_relations + relation integration, 359 lines),memory_type.rs(MemoryType + importance-profile + spec_2589, 160 lines),store.rs(FileMemoryStore backend/provider/ingestion + spec_2553, 440 lines), andsearch.rs(integration memory-search + hybrid/vector-only + migrate-to-provider + memory-tree, 729 lines). Behavior-preserving — internal helpers arepub(super)and re-exported under their original identifiers at the runtime module root;FileMemoryStoreispub use'd from the crate root; public types are re-exported viapub use types::*; submodule tests access runtime-scope symbols viasuper::super::TypeName; shared test helpersScopedEnvVar,memory_backend_env_lock,lifecycle_scope, andlifecycle_entryare promoted topub(super)so sibling test modules can share them. Full split plan in docs/planning/god-file-split-audit-2026-04-23.md.runtime.rswent from 3660 → 71 lines (-98%) and the survivingruntime/tests.rsshrank from 2487 → 249 lines (-90%) across the sub-splits. All 97 tau-memory unit tests remain green throughout.
wasmtime: 25.0.3 → 36wasmparser: 0.225 → 0.232
- Product proof readiness: added
scripts/dev/prove-tau-product.shas the canonical executable local proof path, with--check, live--run,--report <path>machine-readable proof evidence, documented consumer parsing examples, and opt-in--webchat-smokevalidation for the/webchatproduct surface. See docs/guides/canonical-product-proof.md and docs/solutions/patterns/opt-in-product-proof-live-surface-smoke.md.
- M104 remediation baseline artifacts:
.env.examplefor operator-ready environment bootstrap.rustfmt.tomlfor explicit formatting policy anchoring.- Expanded
tau-safetyconformance/regression test coverage.
tasks/tau-gaps-issues-improvements.mdrefreshed with evidence-backed per-item status mapping and follow-up links.
- G8 local embeddings completion and validation.
- G2 context compaction phases 2-5 completion, including warn-tier LLM summarization.
- G16 hot-reload completion.
- G4 branch-as-tool phase 2 runtime orchestration and concurrency controls.
- Memory enhancement closure validation for G5/G6/G7.
- Process-type profile routing and prompt/template hot-reload integration.
- Cargo-fuzz baseline harness and repeatable verification workflow.
- Gateway/dashboard quality and operational hardening waves.
- Skip/react/send-file tool contracts and adapter closure work.
- README and roadmap accuracy refresh waves.
- CI/process gates for milestone/spec alignment and faster preflight checks.
- Earlier milestone history (M1..M54) is captured in
specs/milestones/and associated issue/PR evidence.