All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

0.12.0 - 2026-07-27

Added

  • A total :completion_only common-feature manifest sourced from CliSubprocessCore.ProviderFeatures. Every provider schema now accepts the option shape; Amp, Antigravity, and Cursor fail with an explicit typed capability error when it is requested.
  • Amp and Antigravity SDK-lane carriage for :transport_headless_timeout_ms, keeping finite transport orphan reaping separate from their stream idle timeouts.
  • A 0.12 migration guide and shared dependency-source helper v7 release-DAG coverage.

Changed

  • Require cli_subprocess_core ~> 0.4.0.
  • Move :completion_only from the Claude/Codex-local option schemas into the normalized common option and Zoi schema surfaces while retaining the provider-specific posture implementation in both Core and SDK lanes.
  • Refresh the documented optional SDK train to Amp 0.7.0 and Antigravity 0.2.0.
  • Normalize Cursor to the same dynamically discovered optional-SDK boundary used by Claude, Codex, Amp, and Antigravity. ASM no longer declares cursor_cli_sdk as a package dependency or release prerequisite.

Fixed

  • Elixir 1.20 compiler warnings caused by nil-after-atom clauses, an always-true atom check, and a redundant non-nil predicate.
  • Prevent the unsatisfiable published graph in which Cursor SDK 0.2 required Core ~> 0.3.0 while ASM 0.12 required Core ~> 0.4.0; Cursor core-lane support remains available without the optional SDK.

0.11.0 - 2026-07-27

Added

  • structured_output is now a capability-queryable partial provider feature. ASM.ProviderFeatures.common_feature!/2 and supports_common_feature?/2 report per-provider support and the real wire form (Claude inline JSON on --json-schema, Codex a schema file path on --output-schema), sourced from CliSubprocessCore.ProviderFeatures rather than a second ASM-local catalog.
  • ASM.Result.object and ASM.Message.Result.object carry a provider-returned structured object end to end, from the decoded CliSubprocessCore.Payload.Result through ASM.Event.legacy_payload/1 and ASM.Run.EventReducer. Both are nil when the provider returned no object.
  • :run_deadline_ms, a total wall-clock budget for a whole run (default 600_000, :infinity to opt out, overridable per run or through the :agent_session_manager application environment). Unlike :stream_timeout_ms it never re-arms, so a chatty-but-stuck run terminates instead of running forever. Expiry closes the backend and returns %ASM.Error{kind: :timeout, domain: :runtime}.
  • Owner-scoped sessions. ASM.start_session/1 accepts owner: pid, and the provider form of ASM.query/3 scopes the session it creates to its caller. ASM.Session.OwnerGuard (supervised by the new ASM.Session.GuardSupervisor, outside the subtree it guards) terminates the session subtree and its provider process group when the owner goes down, including an untrappable kill that skips the caller's after block.
  • :completion_only for Claude and Codex: an empty tool set, no settings sources, strict MCP config and plan mode for Claude; a read-only sandbox and ephemeral operation with user configuration, rules, web search, and skills disabled plus approval_policy="never" for Codex. It replaces any caller-supplied permission mode instead of merging with it, and is carried by both the :core and :sdk lanes.

Changed

  • Publish preflight now verifies the exact local sibling release on Hex, so an older package version cannot falsely satisfy release readiness. Nested package tasks resolve the helper-owning repository, and manifest self-entries are excluded from prerequisites.
  • :output_schema is a normalized common ASM option gated by the :structured_output capability, rather than a Codex-only provider option. A provider without that capability now fails with a typed %ASM.Error{} naming the provider, option, and capability instead of a NimbleOptions shape error.

Fixed

  • Claude structured-output requests now reach the Claude Agent SDK lane as a streaming JSON Schema output format. ASM previously accepted :output_schema but silently replaced it with plain :stream_json while deriving SDK options, so the Claude CLI never received --json-schema.
  • The :sdk lane never emitted --output-schema. ASM.ProviderBackend.SDK set output_schema on the Codex thread options but built Codex.Exec.Options without output_schema_path, and ASM bypasses Codex.Thread.build_exec_options/2, the only caller that materializes the file — so a structured-output request produced unconstrained prose that looked like success. The schema is now materialized through CliSubprocessCore.OutputSchemaFile, owned by the run process, and removed when the run ends by any route.
  • ASM.Run.Server now traps exits, so its terminate/2 actually runs when the run supervisor shuts a run down. Previously a session stop left the provider backend and its process group orphaned.
  • ASM.session_id/1 returned nil only for exceptions, while a call to a stopped session exits; it now catches that exit, so ASM.stop_session/1 on an already-collected session is an honest {:error, :not_found}.
  • ASM.start_session/1 rejects a non-pid :owner with a typed :config_invalid error and tears down the just-created subtree instead of silently turning the session into an unowned one.
  • Optional SDK tests no longer scan sibling checkout _build trees or load their transitive beams. Checked-in provider-shape stubs and local fake transports keep the default suite hermetic and aligned with the current SDK contracts. The explicit live-example --sdk-root workflow remains available.
  • Refreshed the zoi lock from 0.18.5 to the current 0.18.7 release.

0.10.0 - 2026-07-13

Added

  • Current GPT-5.6 Sol, Terra, and Luna plus GPT-5.3-Codex-Spark model selection through the shared core, including live defaults and Codex :max/:ultra schema inputs with model-specific validation delegated to CliSubprocessCore.ModelRegistry.
  • Provider/lane capability manifests with support states for Codex, Claude, Amp, Cursor, and Antigravity, including explicit unsupported capability errors for Codex-style host dynamic tools on Amp/Cursor/Antigravity.
  • Cursor Agent CLI is registered as a first-party ASM provider on the core cli_subprocess_core lane, with Cursor options, permission mapping, extension metadata, examples, and live smoke tests.
  • Cursor SDK lane documentation now covers backend selection, strict ProviderSDK.Cursor derivation, live examples, and endpoint publication boundaries.
  • ASM.HostTool specs, requests, and responses plus ASM-local host-tool event kinds for Codex app-server dynamic tool request/response flows.
  • A Codex SDK app-server backend path that advertises dynamicTools, executes registered host tools, responds through Codex.AppServer.respond/3, and projects host-tool lifecycle events.
  • Live-only Codex app-server ASM examples for plain app-server sessions, dynamic host-tool fulfillment, and exact provider-thread resume.
  • Fable resolution regression test pinning fable / claude-fable-5 through finalize_provider_opts and the shared registry catalog.
  • Atom-safety guardrail: .credo.exs with Credo.Check.Warning.UnsafeToAtom enabled (scoped to lib/) plus a scripts/atom_guard.sh CI backstop wired into mix ci (which now runs credo --strict).
  • Secrets guardrail: scripts/secrets_guard.sh in mix ci; .env files gitignored.
  • README documents the deliberate allow_unknown_model default divergence: ASM stays strict-by-default while claude_agent_sdk is permissive-by-default on the same registry machinery.

Changed

  • Restricted the Hex archive to consumer-facing source, guides, the HexDocs example overview, and public documentation/assets; standardized the README on the centered 200px logo with GitHub and MIT badges.
  • Prepared the Hex candidate for Elixir ~> 1.19, cli_subprocess_core ~> 0.2.0, and cursor_cli_sdk ~> 0.1.0; the optional SDK documentation now matches the prepared Claude 0.18 and Amp 0.6 lines.
  • Codex examples and provider guides now cover the current GPT-5.6 model IDs, the strict shared-registry Spark preview path, and the codex_sdk 0.17.0 extension surface.
  • Refreshed compatible dependencies, including Zoi 0.18.5.
  • Renamed the provider adapter-selection policy contract from the old ExecutionPlane.* namespace to the ASM-owned ASM.AdapterSelectionPolicy.v1 vocabulary.

Fixed

  • Distributed test peers now preserve the local prepared dependency precedence instead of loading stale component-era beams from optional SDK build closures.
  • Runtime-only Cursor and Antigravity providers now return a bounded error when presented to the inference endpoint seam instead of raising a function-clause exception.
  • Codex app-server result projection now avoids duplicate final text when a turn emits both streaming deltas and completed assistant-message items, and ASM content projection accepts atom-form content block types.

Security

  • config/runtime.exs snapshots an allowlist (ASM.EnvSnapshot.take/1: provider namespaces plus static selectors) instead of the whole OS environment, so unrelated secrets in the parent process are never copied into inspectable Application config.
  • RuntimeAuth.CodexMaterialization redacts :api_key, :env, and :native_auth_assertion from inspect/1 via @derive Inspect.

Removed

  • Retired the Gemini CLI provider, optional gemini_cli_sdk lane, native extension, examples, and documentation. Antigravity is now ASM's only Google coding-agent provider.

0.9.2 - 2026-04-09

Added

  • Added guides/execution-plane-alignment.md to document how ASM carries execution-surface and execution-environment data without taking ownership of lower transport mechanics.

Changed

  • ASM.Execution.Config now exposes explicit helper functions for the named execution-plane contract list and its smaller provisional subset: execution_plane_contracts/0 and provisional_minimal_lane_contracts/0.
  • README, examples, and the HexDocs menu now include the execution-plane alignment material as part of the main ASM documentation set.
  • Bumped the published package version to 0.9.2.

0.9.1 - 2026-04-08

Changed

  • ASM no longer normalizes Codex permission_mode: :auto onto the provider's workspace-write auto-edit path. Codex stays supported on the shared ingress for :default, :bypass, and :plan, while provider-native auto-edit remains a direct codex_sdk concern.

Fixed

  • The shared ASM Codex contract now avoids routing normalized :auto through a current Codex CLI path that creates a repo-local .codex artifact in the workspace root.
  • Codex bridge docs/examples now show :default on the ASM side and explain when callers should drop down to provider-native codex_sdk thread options.

0.9.0 - 2026-04-06

Added

  • A rebuilt ASM runtime centered on OTP-native session/run orchestration for Claude, Codex, Gemini, and Amp with one normalized query/stream API.
  • Transport-neutral execution surfaces for local subprocess, SSH, and remote-node backed runs, including shared session-control recovery orchestration.
  • Provider backend lanes that split common cli_subprocess_core execution from optional SDK-backed execution, with backend-aware model payload resolution and normalized provider registry metadata.
  • Optional provider-SDK discovery and bridge surfaces for Claude and Codex, while keeping Gemini and Amp honest as common-surface providers unless their SDK lane is explicitly available.
  • ASM.InferenceEndpoint for publishing the landed CLI provider set as completion/streaming endpoint-shaped targets.
  • A new docs/example/test set focused on lane selection, provider backends, remote execution, live adapter proofs, and endpoint publication.

Changed

  • Breaking change: the package was substantially reshaped around the ASM namespace and a normalized orchestration kernel instead of the much broader AgentSessionManager architecture shipped in v0.8.0.
  • The public package story now centers on ASM.start_link/1, ASM.query/3, ASM.stream/3, provider backend lanes, and run/session-scoped %ASM.Event{} envelopes rather than provider-local transport ownership.
  • cli_subprocess_core is now the only required shared runtime dependency; provider SDKs are additive opt-ins, and ASM finalizes provider options by handing backend-specific payload resolution down to the shared core/SDK layer.
  • Boundary enforcement and schema normalization were tightened around the new package shape, with Boundary, Zoi, and NimbleOptions carrying the public ingress and dynamic boundary work.
  • README, guides, examples, and package metadata were rewritten around the new release model, including explicit documentation for provider backends, endpoint publication, remote execution, and provider-SDK extension seams.

Removed

  • The old v0.8.0 package center of gravity is no longer present as a first-class runtime story: the prior persistence/query/storage adapters, direct provider adapters, shell-runner path, and much of the routing, rendering, workspace, PubSub, policy, and migration-era example/documentation surface were removed or reduced to narrower extension/compatibility seams.

Fixed

  • Boundary enforcement, startup error surfacing, interrupt handling, and SSH example coverage were hardened around the rebuilt runtime contract.
  • Dialyzer now stores its core and project PLTs inside priv/plts, so the release verification floor no longer depends on a writable global Mix home.

0.8.0 - 2026-02-10

Added

  • Persistence subsystem with production-grade adapters and maintenance/query surfaces
    • EctoSessionStore adapter with migrations and schemas (supports PostgreSQL, SQLite via Ecto.Adapters.SQLite3)
    • S3ArtifactStore adapter for S3-compatible object storage
    • CompositeSessionStore adapter combining SessionStore + ArtifactStore
    • QueryAPI and Maintenance ports with Ecto implementations (EctoQueryAPI, EctoMaintenance)
    • Persistence modules: EventPipeline, EventValidator, RetentionPolicy, ArtifactRegistry
  • flush/2 and append_events/2 callbacks on the SessionStore port
    • flush/2 atomically persists final session/run state (and any queued events) in transactional backends like Ecto
    • append_events/2 persists a batch of events with atomic sequence assignment (used by EventPipeline.process_batch/3)
    • Implemented in EctoSessionStore, InMemorySessionStore, and CompositeSessionStore
  • EventBuilder module (AgentSessionManager.Persistence.EventBuilder) for pure event normalize/enrich/validate processing without persistence
  • ExecutionState module (AgentSessionManager.Persistence.ExecutionState) for in-memory run state accumulation (session, run, events, provider metadata)
  • OptionalDependency module for standardized error reporting when optional dependencies (Ecto, ExAws) are missing
  • Runtime.ExitReasons module for shared adapter/store exit-reason classification across SessionManager + provider boundaries
  • SessionManager subsystem modules for cleaner orchestration boundaries
    • InputMessageNormalizer
    • ProviderMetadataCollector
  • Top-level persistence convenience API on AgentSessionManager
    • session_store/1 for SessionStore refs (pid or {Module, context})
    • query_api/1 for QueryAPI refs
    • maintenance/1 for Maintenance refs
  • Conditional compilation for optional Ecto, AWS, and provider SDK dependencies
    • EctoSessionStore, EctoQueryAPI, EctoMaintenance, Ecto migrations/schemas wrapped in conditional blocks
    • S3ArtifactStore.ExAwsClient provides fallback when ExAws is missing
    • ArtifactRegistry Ecto-dependent metadata tracking wrapped with fallback logic
    • AmpAdapter, ClaudeAdapter, and CodexAdapter compile only when their SDK deps are available
    • Library can be used without Ecto, ExAws, or provider SDK dependencies installed
  • SessionManager store-failure hardening
    • All SessionStore calls wrapped in safe_store_call/2
    • Store process exits converted to :storage_connection_failed errors
    • Prevents SessionServer execution tasks from crashing when store teardown races with failed-run finalization
  • ProviderAdapter error normalization
    • call_with_error/4 and call_exit_error/4 for structured exit normalization
    • :noproc, :timeout, and unexpected exits normalized into Core.Error structs
    • provider_unavailable tolerance in cancel_run request path
  • Core.Serialization module consolidating atomize_keys/1 and stringify_keys/1 across EctoSessionStore and EctoQueryAPI
  • Shared Ecto converters module (EctoSessionStore.Converters) used by both store and query adapters for schema <-> core transformations
  • Ecto migrations (V1 base schema, V2 provider/artifact fields, V3 foreign keys) and Ecto schemas for sessions, runs, and events
  • Event struct extensions: schema_version, provider, correlation_id fields
  • Session struct extension: deleted_at for soft-delete support
  • Persistence test hardening suites for regression resistance
    • ecto_session_store_concurrency_test.exs (concurrent append/session consistency)
    • session_store_contract_multi_impl_test.exs (contract tests across InMemory + Ecto refs)
    • ecto_session_store_migration_compat_test.exs and ecto_session_store_migration_down_test.exs (migration prerequisite + rollback coverage)
  • Persistence live examples: sqlite_session_store_live.exs, ecto_session_store_live.exs, s3_artifact_store_live.exs, composite_store_live.exs, persistence_query.exs, persistence_maintenance.exs, persistence_multi_run.exs, persistence_live.exs, persistence_s3_minio.exs
  • Approval gates and human-in-the-loop policy enforcement
    • New request_approval policy action as a valid on_violation value, emitting tool_approval_requested events without automatically cancelling the run
    • Strictness hierarchy for policy stacking: cancel > request_approval > warn
    • Core event types for tool_approval_requested, tool_approval_granted, and tool_approval_denied with validation and persistence support
    • cancel_for_approval/4 in SessionManager for streamlined run cancellation pending human review
    • TranscriptBuilder synthetic tool responses when a run is awaiting approval, reflecting the paused state in the transcript
    • Comprehensive tests for runtime enforcement and stacking, approval_gates.exs example, and updated policy enforcement guide
  • Interactive interrupt example (interactive_interrupt.exs) demonstrating mid-stream run cancellation and follow-up prompts within the same session
  • Case-insensitive tool name matching in approval_gates.exs policy rules (lowercase and title case variants)
  • Shell Runner (ShellAdapter provider and Workspace.Exec)
    • ShellAdapter implements ProviderAdapter as a GenServer with Task.Supervisor-backed concurrent execution
    • Three input formats: string (shell-wrapped via /bin/sh -c), structured map (explicit command/args/cwd), and messages (compatibility extraction from user content)
    • Full canonical event sequence: run_started, tool_call_started, tool_call_completed/failed, message_received, run_completed/failed/cancelled with provider: :shell attribution
    • Security controls: allowed_commands and denied_commands lists with denylist-takes-precedence semantics
    • Configurable success_exit_codes for treating non-zero exits as success
    • Cancellation kills both the Elixir task and underlying OS process via pid
    • Workspace.Exec for low-level command execution via Port.open with timeout, output capture, max output bytes truncation, environment variables, and OS process management
    • run_streaming/3 returns lazy Stream.resource for incremental output
    • on_output callback support in structured map input for streaming
    • Advertises command_execution and streaming capabilities
    • New guide: guides/shell_runner.md
    • New example: shell_exec.exs demonstrating mixed provider + shell execution
  • CodexAdapter ItemStarted/ItemCompleted event handling
    • Emit tool_call_started and tool_call_completed events for Codex command execution, file change, and MCP tool call items
    • Normalize CommandExecution and FileChange item types to canonical tool event payloads
    • ID-based agent_messages tracking with streamed_agent_message_ids to avoid content duplication across multi-message turns
    • active_tools state preserves tool inputs during the call lifecycle
  • Ash Framework persistence integration as an optional alternative to raw Ecto adapters
    • New Ash resources and domain for asm_* tables
    • New adapters: AshSessionStore, AshQueryAPI, and AshMaintenance
    • Atomic per-session sequence assignment via AssignSequence
    • Ash-focused tests, guide (guides/ash_session_store.md), and live example (examples/ash_session_store.exs)
  • PubSub integration for real-time event broadcasting via Phoenix PubSub
    • PubSubSink rendering sink broadcasts events to configurable PubSub topics
    • AgentSessionManager.PubSub helper module with event_callback/2 and subscribe/2
    • AgentSessionManager.PubSub.Topic for canonical topic naming (asm:session:{id}, asm:session:{id}:run:{rid})
    • Optional dependency on phoenix_pubsub ~> 2.1 with graceful stub fallback
  • AgentSessionManager.WorkflowBridge module for workflow/DAG engine integration
  • WorkflowBridge.StepResult normalized result type with routing signals
  • WorkflowBridge.ErrorClassification for retry/failover/abort decisions
  • step_execute/3 supporting one-shot and multi-run execution modes
  • setup_workflow_session/3 and complete_workflow_session/3 lifecycle helpers
  • classify_error/1 mapping ASM errors to workflow routing actions
  • examples/workflow_bridge.exs live example
  • guides/workflow_bridge.md integration guide
  • Secrets redaction for persisted events (EventRedactor module)
    • Configurable pattern-based secret detection and [REDACTED] replacement
    • Integrates into EventBuilder pipeline between build and enrich steps
    • Default patterns for AWS keys, AI provider tokens, GitHub PATs, JWTs, passwords, connection strings, private keys, environment variables
    • Custom pattern support via application config or per-pipeline context override
    • redact_map/2 public API for user callback and telemetry handler wrapping
    • Opt-in via redaction_enabled: true (default: disabled for backward compatibility)
    • Telemetry event [:agent_session_manager, :persistence, :event_redacted] emitted on redaction
    • Five new Config keys: redaction_enabled, redaction_patterns, redaction_replacement, redaction_deep_scan, redaction_scan_metadata
  • StudioRenderer — CLI-grade interactive renderer for terminal display
    • Human-readable tool summaries instead of raw JSON output
    • Status symbols: (running), (success), (failure), (info)
    • Three tool output modes: :summary, :preview, :full
    • Clean text streaming with indentation and visual phase separation
    • Automatic non-TTY fallback (no cursor control when piped)
    • Studio.ANSI shared utility module for colors, cursor control, and symbols
    • Studio.ToolSummary per-tool summarization for bash, Read, Write, Edit, Glob, Grep, Task, WebFetch, WebSearch
  • New example: rendering_studio.exs demonstrating StudioRenderer with all three tool output modes
  • New guide section: StudioRenderer in guides/rendering.md
  • CostCalculator with model-aware pricing and USD cost tracking (AgentSessionManager.Cost.CostCalculator)
    • Three-tier model resolution: exact match, prefix match with date suffix stripping, provider default fallback
    • Cache token support for Claude prompt caching (cache_read_tokens, cache_creation_tokens)
    • cost_usd field added to Run struct with serialization support
    • get_cost_summary/2 callback on QueryAPI with per-run aggregation (total, by_provider, by_model)
    • Policy Runtime model-aware rate resolution via CostCalculator.resolve_rates/3
    • MigrationV4 adding cost_usd float column to asm_runs table
    • Cost display in CompactRenderer, VerboseRenderer, and JSONLSink
    • SessionManager finalization prefers SDK-provided total_cost_usd, falls back to CostCalculator
    • New guide: guides/cost_tracking.md
    • New example: cost_tracking.exs
  • AgentSessionManager.Config centralization of all operational defaults
    • All library timeouts, buffer sizes, and limits moved into centralized Config with three-layer resolution (process-local, application env, hardcoded fallback)
    • New guide: Configuration Reference
  • AgentSessionManager.Models central registry for model identifiers and pricing
    • Runtime model name, default provider model, and per-token pricing lookup
    • AgentSessionManager.Test.Models for test fixture management
    • New guide: Model Configuration

Changed

  • SessionStore is the single execution persistence boundary -- event persistence remains per-event via append_event_with_sequence/2, with append_events/2 available for batch paths and flush/2 used during finalization
  • SessionStore refs now support both pid and {Module, context} dispatch -- Ecto-backed usage can call adapters directly (for example {EctoSessionStore, Repo}) instead of routing through a single GenServer
  • QueryAPI and Maintenance refactored to module-backed refs -- {EctoQueryAPI, Repo} and {EctoMaintenance, Repo} replace dedicated GenServer adapters, removing process lifecycle overhead
  • EventPipeline processing -- builds events via EventBuilder; process/3 persists per-event with append_event_with_sequence/2, while process_batch/3 persists via append_events/2
  • Session lifecycle event persistence unified through EventPipeline so internal lifecycle emissions and adapter callback events use the same validation/persistence path
  • Session finalization integrates ExecutionState for consistent in-memory accumulation and final flush behavior
  • Provider metadata extraction no longer depends on run-scoped SessionStore.get_events/3 read-back; metadata is captured from callback/result event data during execution
  • ArtifactRegistry decoupled from adapter schema modules via behaviour-based injection to preserve persistence layering
  • InMemorySessionStore event appends moved to queue-based buffering to avoid O(n) append overhead under load
  • CompositeSessionStore direct-call timeout handling now propagates wait_timeout_ms and isolates artifact failures from session persistence paths
  • crypto.strong_rand_bytes used for workspace artifact keys instead of System.unique_integer
  • Current-only contract cleanup (backward-compatibility helpers removed):
    • Boolean continuation value true is no longer accepted; use :auto, :replay, :native, or false
    • Adapter tool events emit canonical keys only: tool_call_id, tool_name, tool_input, tool_output; provider-native aliases (call_id, tool_use_id, arguments, input, output, content) removed
    • TranscriptBuilder and renderers consume canonical tool keys only; fallback chains through legacy keys removed
    • Event.from_map/1 requires explicit schema_version (integer >= 1); nil/missing no longer defaults to 1
    • QueryAPI and Maintenance accept module-backed {Module, context} refs only; GenServer dispatch paths return :validation_error
    • SessionServer.status/1 no longer includes the legacy active_run_id status field
    • Session provider metadata is stored under session.metadata[:provider_sessions] without top-level duplication; top-level :provider_session_id and :model keys are no longer merged
  • ClaudeAdapter refactoring: removed execute_with_mock_sdk path and receive-based event stream processing (~300 lines); added stop_reason tracking through streaming context, :cancelled result subtype handling from SDK stream, and extracted extract_usage_counts, extract_stop_reason, emit_success_events, maybe_emit_run_completed helpers
  • EventBuilder no longer duplicates provider into event.metadata; provider lives on Event.provider struct field only
  • EventNormalizer removes type inference heuristics (content-key sniffing, status-based refinement, fuzzy type mappings); resolve_type validates against Event.valid_type?/1 using canonical names only
  • MockSDK gains query/3 interface returning Stream.resource with ClaudeAgentSDK.Message emission, including tool_use content block handling and error scenarios
  • codex_sdk dependency updated from path ref to ~> 0.8.0 hex package
  • PubSub defaults are now configured per use (PubSubSink / PubSub.event_callback) and are no longer exposed as global AgentSessionManager.Config keys
  • FileSink ANSI strip regex extended to also remove cursor control sequences (\r, \e[2K, \e[NA)
  • Execution timeout propagated to underlying SDK options: Amp (stream_timeout_ms) and Claude (timeout_ms) with configurable fallback
  • Unbounded/infinite timeout support across all adapters with 7-day (604,800,000 ms) emergency cap to prevent runaway processes
  • Codex adapter sdk_opts selective merge filtering against target module keys (supports both atom and string keys)
  • Codex adapter extracts confirmed model names and reasoning effort from thread metadata events
  • Amp adapter includes model state in execution context
  • Ash query filtering enhancements: min_tokens filter, since/until temporal filtering, multi-status filtering, strict limit validation, improved cursor pagination
  • All adapters (Shell, Ecto, Ash) use dynamic configuration from Config module
  • RetentionPolicy pulls defaults from central Config
  • ConcurrencyLimiter uses configurable parallel session limits from Config
  • CostCalculator uses centralized pricing table from Models
  • ClaudeAdapter and examples use dynamic default model from Models
  • Ash adapters use expr macro in query filters; large functions broken into focused helpers
  • WorkflowBridge keyword list normalization improved for adapter options and continuation parameters
  • Ash tests gated behind RUN_ASH_TESTS environment variable
  • Provider adapters (CodexAdapter, AmpAdapter, ClaudeAdapter) now normalize provider failures into a stable provider_error payload and preserve provider-specific extras in Error.details
  • Session/run failure paths now persist and emit structured provider diagnostics (provider_error, details) alongside legacy error_message
  • Added shared AgentSessionManager.Core.ProviderError normalization to enforce the contract:
    • provider, kind, message, exit_code, stderr, truncated?
    • Truncation limits are configurable via :error_text_max_bytes and :error_text_max_lines

Fixed

  • Cursor pagination correctness (C-1) -- cursor tokens are decoded and applied via keyset filters with explicit ordering validation; invalid cursors return structured errors instead of silently repeating page 1
  • delete_session/2 and hard-delete cascade safety (C-2, C-5) -- session/run/event deletion paths are transactional and delete dependent rows deterministically to prevent orphaned records
  • Event persistence error handling (C-3) -- EventPipeline persistence failures are surfaced to callers and SessionManager callback/store interactions are protected from teardown crashes
  • Ecto insert crash path (C-4) -- bang inserts in GenServer call paths replaced with safe insert + rollback handling to avoid store process crashes
  • Migration prerequisite mismatch (C-6) -- EctoSessionStore now fails fast when required V2 columns are missing, preventing runtime crashes from V1-only schemas
  • Maintenance correctness (M-1, M-2, M-9) -- health checks use max(sequence_number), retention age checks use updated_at, and protected prune event types include run_started/run_completed
  • Optional dependency error semantics (M-10) -- missing optional dependencies now normalize to :dependency_not_available instead of generic storage failure codes
  • Composite direct call timeout behavior (M-8 scoped) -- CompositeSessionStore.get_events/3 correctly adjusts call timeout for long-poll options
  • Event redaction now scans nested provider_error payloads (including stderr) on failure events (:error_occurred, :run_failed, :session_failed)

Removed

  • Persistence abstractions removed in favor of SessionStore + flush/2:
    • AgentSessionManager.Ports.DurableStore
    • AgentSessionManager.Adapters.NoopStore
    • AgentSessionManager.Adapters.SessionStoreBridge
  • Raw SQLiteSessionStore replaced by EctoSessionStore + ecto_sqlite3
  • Event emitter path removed; event build/validation/persistence flows through EventBuilder + EventPipeline

See guides/migrating_to_v0.8.md for migration details.

Documentation

  • Persistence guides: persistence_overview.md, ecto_session_store.md, sqlite_session_store.md, s3_artifact_store.md, composite_store.md, event_schema_versioning.md, custom_persistence_guide.md, migrating_to_v0.8.md
  • Persistence module group and guides added to HexDocs configuration
  • New guide: guides/shell_runner.md covering Workspace.Exec and ShellAdapter usage, input formats, configuration, event mapping, security controls, and mixed AI+shell workflows
  • Update guides/provider_adapters.md with ShellAdapter section, event mapping table, and Shell Runner module group in HexDocs
  • Update README.md with approval gate functionality, interactive interrupt example, and Shell Runner feature
  • Update examples/README.md with interactive_interrupt.exs, approval_gates.exs, and shell_exec.exs entries
  • Add interactive_interrupt.exs and shell_exec.exs to run_all.sh automated test suite
  • Update README.md and persistence overview with per-event persistence and flush/2 finalization details
  • Document V2 migration prerequisites + V3 foreign-key migration expectations for SQLite and PostgreSQL flows
  • Document cursor semantics/order requirements, SessionStore ref shapes (pid vs {Module, context}), and optional SDK dependency behavior
  • Update examples/README.md with all persistence adapter and query/maintenance examples
  • Rewrite guides/event_schema_versioning.md for strict-only contract (no backward-compatible defaults)
  • Document structured provider_error propagation, stderr truncation limits, and failure-event payload semantics across README.md, guides/error_handling.md, guides/events_and_streaming.md, and related rendering/streaming guides
  • Remove "backward compatible" / "legacy" language from all guides
  • Update guides/session_continuity.md: remove boolean true documentation, simplify mode table
  • Update guides/provider_adapters.md: remove alias emission notes, canonical keys only

0.7.0 - 2026-02-09

Added

  • Generic rendering system with pluggable Renderer x Sink architecture (AgentSessionManager.Rendering)
    • Rendering.stream/2 orchestrator consumes any Enumerable of event maps, renders each event, and writes to all sinks simultaneously
    • Full lifecycle: init -> render loop -> finish -> flush -> close
  • Renderer behaviour with three built-in implementations
    • CompactRenderer - single-line token format (r+, r-, t+Name, t-Name, >>, tk:N/M, msg, !, ?) with optional ANSI color support via :color option
    • VerboseRenderer - line-by-line bracketed format ([run_started], [tool_call_started], etc.) with inline text streaming and labeled fields
    • PassthroughRenderer - no-op renderer returning empty iodata for every event, for use with programmatic sinks
  • Sink behaviour with four built-in implementations
    • TTYSink - writes rendered iodata to a terminal device (:stdio default), preserving ANSI codes
    • FileSink - writes rendered output to a plain-text file with ANSI codes stripped; supports both :path (owns the file) and :io (pre-opened device, caller manages lifecycle) options
    • JSONLSink - writes events as JSON Lines with :full mode (all fields, ISO 8601 timestamps) and :compact mode (abbreviated type codes, millisecond epoch timestamps)
    • CallbackSink - forwards raw events and rendered iodata to a 2-arity callback function for programmatic processing
  • ANSI color support in CompactRenderer with configurable :color option (default true)
  • StreamSession one-shot streaming session lifecycle module
    • StreamSession.start/1 replaces ~35 lines of hand-rolled boilerplate (store + adapter + task + Stream.resource + cleanup) with a single function call
    • Returns {:ok, stream, close_fun, meta} - a lazy event stream, idempotent close function, and metadata map
    • Automatic InMemorySessionStore creation when no store is provided
    • Adapter startup from {Module, opts} tuples; passes through existing pids/names without ownership
    • Ownership tracking: only terminates resources that StreamSession created
    • Configurable idle timeout (default 120s) and shutdown grace period (default 5s)
    • Error events emitted for adapter failures, task crashes, exceptions, and timeouts (never crashes the consumer)
    • Atomic idempotent close via :atomics.compare_exchange
  • StreamSession.Supervisor convenience supervisor for production use
  • StreamSession.Lifecycle resource acquisition and release (store, adapter, task)
  • StreamSession.EventStream lazy Stream.resource with receive-based state machine
  • Four new rendering examples: rendering_compact.exs, rendering_verbose.exs, rendering_multi_sink.exs, rendering_callback.exs
  • New example: stream_session.exs demonstrating StreamSession in rendering and raw modes
  • New guides: guides/rendering.md, guides/stream_session.md
  • Rendering test helpers in test/support/rendering_helpers.ex
  • Full test coverage for all renderers, sinks, and StreamSession

Changed

  • Rendering examples refactored to use StreamSession.start/1, eliminating duplicated build_event_stream boilerplate from each
  • examples/run_all.sh updated with StreamSession and rendering example entries

Documentation

  • Add guides/rendering.md and guides/stream_session.md to HexDocs extras and "Core Concepts" group
  • Add Rendering and Stream Session module groups to HexDocs
  • Update examples/README.md with rendering and StreamSession example documentation
  • Add rendering and StreamSession sections to README.md
  • Bump installation snippets in README.md and guides/getting_started.md to ~> 0.7.0

0.6.0 - 2026-02-08

Added

  • Normalized max_turns option for controlling agentic loop turn limits across all adapters
    • Claude: nil (default) = unlimited turns, integer = pass --max-turns N to CLI
    • Codex: nil (default) = SDK default of 10, integer = override via RunConfig
    • Amp: stored but ignored (CLI-enforced, no SDK knob)
  • Normalized system_prompt option for configuring system prompts across adapters
    • Claude: maps to system_prompt on ClaudeAgentSDK.Options
    • Codex: maps to base_instructions on Codex.Thread.Options
    • Amp: stored in state (no direct SDK equivalent)
  • sdk_opts passthrough for arbitrary provider-specific SDK options
    • All adapters accept :sdk_opts keyword list, merged into the underlying SDK options struct
    • Normalized options (:permission_mode, :max_turns, etc.) always take precedence over sdk_opts
    • Unknown keys are silently ignored (only struct-valid fields are applied)
  • Normalized permission modes via AgentSessionManager.PermissionMode with provider-specific mapping
    • Five modes: :default, :accept_edits, :plan, :full_auto, :dangerously_skip_permissions
    • PermissionMode.all/0, valid?/1, and normalize/1 for validation and string/atom coercion
    • ClaudeAdapter maps :full_auto and :dangerously_skip_permissions to permission_mode: :bypass_permissions on ClaudeAgentSDK.Options
    • CodexAdapter maps :full_auto to full_auto: true and :dangerously_skip_permissions to dangerously_bypass_approvals_and_sandbox: true on Codex.Thread.Options
    • AmpAdapter maps :full_auto and :dangerously_skip_permissions to dangerously_allow_all: true on AmpSdk.Types.Options
    • :accept_edits and :plan are Claude-specific; no-op on Codex and Amp adapters
    • All three adapters accept :permission_mode option on start_link/1
    • ClaudeAdapter execute_with_agent_sdk now forwards built SDK options through query/3 (was %{})
  • Long-poll cursor reads via optional wait_timeout_ms parameter on SessionStore.get_events/3
    • InMemorySessionStore implements deferred-reply long-poll using GenServer.reply/2 without blocking the server loop
    • SessionManager.stream_session_events/3 forwards wait_timeout_ms to the store, eliminating busy polling when supported
    • Stores that do not support wait_timeout_ms ignore it and fall back to immediate return
    • cursor_wait_follow.exs live example demonstrating long-poll follow
  • Adapter event metadata persistence in SessionManager.handle_adapter_event/4
    • Adapter-provided DateTime timestamps stored in Event.timestamp instead of DateTime.utc_now()
    • Adapter-provided metadata map merged into Event.metadata
    • Event.metadata[:provider] always set to the adapter's provider name string
  • Native continuation modes for session continuity
    • :continuation option expanded to accept :auto, :replay, :native, true, and false
    • :native mode uses provider-native session continuation (errors if unsupported)
    • :replay mode always replays transcript from events regardless of provider support
    • :auto mode (and true alias) uses native when available, falls back to replay
  • Token-aware transcript truncation via continuation_opts
    • max_chars -- hard character budget for transcript content
    • max_tokens_approx -- approximate token budget using 4-chars-per-token heuristic
    • Truncation keeps the most recent messages within the lower effective limit
  • Per-provider continuation handles stored under session.metadata[:provider_sessions] keyed map for multi-provider sessions
  • Workspace artifact storage via ArtifactStore port and FileArtifactStore adapter
    • Large patches stored as artifacts with patch_ref in run metadata instead of embedding raw patches
    • ArtifactStore.put/4, get/3, delete/3 API (opts optional)
    • Without an artifact store configured, patches are embedded directly
  • Git snapshot untracked file support using alternate GIT_INDEX_FILE to stage all content without mutating HEAD
    • Snapshot metadata includes head_ref, dirty, and includes_untracked fields
  • Hash backend configurable ignore rules via ignore: [paths: [...], globs: [...]]
  • Weighted provider routing via strategy: :weighted with custom weight maps and health-based score penalties
    • Score formula: weight - failure_count * 0.5; ties broken by prefer order
    • Per-run weight overrides via adapter_opts: [routing: [weights: ...]]
  • Session stickiness via sticky_session_id in routing options with configurable sticky_ttl_ms
    • Best-effort: falls back to normal selection when sticky adapter is unavailable
  • Circuit breaker for per-adapter fault isolation (:closed / :open / :half_open states)
    • Pure-functional data structure stored in router state, no extra processes
    • Configurable failure_threshold, cooldown_ms, and half_open_max_probes
  • Routing telemetry events: [:agent_session_manager, :router, :attempt, :start | :stop | :exception]

  • Policy stacks via policies: [...] list option with deterministic left-to-right merge semantics
    • Names joined with +, limits overridden by later values, tool rules concatenated, strictest on_violation wins
  • Provider-side enforcement via AdapterCompiler compiling policy rules to adapter_opts
    • Deny rules to denied_tools, allow rules to allowed_tools, token limits to max_tokens
    • Reactive enforcement remains the safety net alongside provider-side hints
  • Policy preflight checks reject impossible policies (empty allow lists, zero budgets, contradictory rules) before adapter execution
  • Multi-slot concurrent session runtime (max_concurrent_runs > 1) in SessionServer
    • Submitted runs queue in FIFO order, dequeued as slots free up
    • Automatic slot release on completion, failure, cancellation, and task crash
  • Durable subscriptions with gap-safe backfill + live delivery in SessionServer
    • subscribe/2 with from_sequence: replays stored events then follows live appends
    • Cursor-based resumption after disconnect: re-subscribe with last_seen_seq + 1
  • Transcript caching in SessionServer using TranscriptBuilder.update_from_store/3 for incremental updates
    • Cache reduces store reads from O(total_events) to O(new_events) per run
    • Invalidated on error; correctness does not depend on cache
  • Runtime telemetry events under [:agent_session_manager, :runtime, ...] namespace
    • run:enqueued, run:started, run:completed, run:crashed, drain:complete
  • ConcurrencyLimiter and ControlOperations integration with SessionServer via :limiter and :control_ops options
    • Crash-safe acquire/release and cancellation routing through the runtime layer
  • New examples: cursor_wait_follow.exs, routing_v2.exs, policy_v2.exs, session_concurrency.exs
  • New guide: guides/advanced_patterns.md covering cross-feature integration patterns

Fixed

  • ClaudeAdapter max_turns: 1 hardcoding -- Claude was limited to a single turn, preventing tool results from being fed back to the model. Now defaults to nil (unlimited).
  • ClaudeAdapter streaming halted on tool use -- handle_streaming_event(%{type: :message_stop}) unconditionally halted the stream, cutting off multi-turn tool use. Now continues when stop_reason is "tool_use", allowing the CLI to execute tools and deliver subsequent turns.
  • ClaudeAdapter missing cwd passthrough -- The adapter never passed cwd to ClaudeAgentSDK.Options, so the Claude CLI ran in the Elixir process's working directory instead of the configured project directory. Now accepts :cwd option and passes it through.
  • ClaudeAdapter setting_sources: ["user"] hardcoding -- removed; use sdk_opts: [setting_sources: [...]] to configure.

Changed

  • SessionStore port get_events/3 now accepts optional wait_timeout_ms parameter (non-breaking; stores may ignore it)
  • InMemorySessionStore extended with waiter tracking for long-poll support
  • session_continuity.exs and workspace_snapshot.exs examples updated with Phase 2 features
  • examples/run_all.sh updated with full Phase 2 provider matrix

Documentation

  • Add routing and runtime telemetry event tables with measurements and metadata to guides/telemetry_and_observability.md
  • Expand AdapterCompiler section in guides/policy_enforcement.md with mapping rules table, merged policy compilation, and provider support matrix
  • Add multi-slot worked example and transcript caching section to guides/session_server_runtime.md
  • Add new Phase 2 examples to guides/live_examples.md
  • Add guides/advanced_patterns.md covering routing + policies, SessionServer + subscriptions + workspace, stickiness + continuity, and policy + workspace + artifacts
  • Update guides/cursor_streaming_and_migration.md with long-poll reference implementation
  • Update guides/session_continuity.md with continuation modes, token-aware truncation, and per-provider handles
  • Update guides/workspace_snapshots.md with artifact store, untracked file support, and ignore rules
  • Update guides/provider_routing.md with weighted routing, stickiness, circuit breaker, and routing telemetry
  • Update guides/policy_enforcement.md with policy stacks, provider-side enforcement, and preflight checks
  • Update guides/session_server_runtime.md with multi-slot concurrency and operational APIs
  • Update guides/session_server_subscriptions.md with durable subscriptions and multi-slot interleaving
  • Bump installation snippets in README.md and guides/getting_started.md to ~> 0.6.0

0.5.1 - 2026-02-07

Changed

  • Canonical tool event payloads across all three adapters (Claude, Codex, Amp)
    • All tool_call_started, tool_call_completed, and tool_call_failed events now emit canonical keys: tool_call_id, tool_name, tool_input, and tool_output
    • Adapters emit canonical keys only (tool_call_id, tool_name, tool_input, tool_output)
    • normalize_tool_input/1 helper added to each adapter to guarantee tool_input is always a map
    • find_tool_call/2 helper added to AmpAdapter to enrich tool_call_completed and tool_call_failed events with tool_name and tool_input from the originating tool call

Documentation

  • Update guides/provider_adapters.md with canonical tool event payload reference
  • Update guides/session_continuity.md with canonical tool_call_id guidance
  • Bump installation snippets in README.md and guides/getting_started.md to ~> 0.5.1

0.5.0 - 2026-02-07

Added

  • AmpAdapter for Sourcegraph Amp provider integration, bringing the adapter count to three (Claude, Codex, Amp)
    • Streaming execution, tool call handling, and cancel support via transport close
    • Amp SDK message types mapped to canonical normalized events
    • amp_direct.exs example demonstrating threads, permissions, MCP, and modes
  • Cursor-backed event streaming with durable per-session sequence numbers
    • append_event_with_sequence/2 and get_latest_sequence/2 callbacks on the SessionStore port
    • :after and :before cursor filters on get_events/3 for sequence-based pagination
    • SessionManager.stream_session_events/3 for resumable follow/poll consumption across reconnects
    • cursor_pagination.exs and cursor_follow_stream.exs live provider examples
  • Session continuity with provider-agnostic transcript reconstruction
    • Transcript struct and TranscriptBuilder with from_events/2, from_store/3, and update_from_store/2
    • Sequence-based ordering with timestamp and deterministic tie-breaker fallbacks
    • Streaming chunk collapse into single assistant messages
    • Canonical tool call ID handling via tool_call_id
    • continuation: :auto and continuation_opts support in execute_run/4 and run_once/4
    • Transcript-aware prompt building in all three adapters
    • session_continuity.exs live provider example
  • Workspace snapshots with pre/post snapshot, diff, and optional rollback instrumentation
    • Workspace service with GitBackend (snapshots, diffs, patch capture, rollback) and HashBackend (snapshots and diffs only)
    • Snapshot and Diff structs with to_map and summary helpers
    • :workspace_snapshot_taken and :workspace_diff_computed event types
    • Run metadata enrichment with compact diff summaries
    • workspace: [...] option support in execute_run/4 and run_once/4
    • workspace_snapshot.exs live provider example
  • Provider routing via ProviderRouter implementing the ProviderAdapter behaviour
    • Capability-driven adapter selection with type+name and type-only matching
    • RoutingPolicy with prefer/exclude ordering and attempt limiting
    • Simple in-process health tracking with consecutive-failure counts and cooldown-based temporary skipping
    • Retryable failover up to configured attempt limit (only for Error.retryable?/1 errors)
    • Cancel routing to the adapter currently handling the active run
    • Routing metadata (routed_provider, routing_attempt, failover_from, failover_reason) attached to results and events
    • provider_routing.exs live provider example
  • Policy enforcement opt-in per execution via :policy in execute_run/4 and run_once/4
    • Policy struct with limits (max_total_tokens, max_duration_ms, max_tool_calls, max_cost_usd), tool rules (allow/deny), and on_violation action (:cancel or :warn)
    • Evaluator for pure policy checks against runtime state snapshots
    • Runtime GenServer for mutable per-run counters and single-cancel semantics
    • :policy_violation event type and error code
    • Cancel mode overrides provider success; warn mode preserves success with violation metadata
    • Optional cost-limit enforcement using configured provider token rates
    • policy_enforcement.exs live provider example
  • SessionServer opt-in per-session runtime GenServer with FIFO queueing and subscriptions
    • submit_run/3, await_run/3, execute_run/3, cancel_run/2, subscribe/2, unsubscribe/2, status/1 API
    • Strict sequential execution (MVP constraint: max_concurrent_runs must be 1)
    • RunQueue pure FIFO data structure with enqueue/dequeue/remove and max size enforcement
    • Queued run cancellation marks :cancelled in store with :run_cancelled event without reaching adapter
    • Store-backed subscriptions delivering {:session_event, session_id, event} with from_sequence cursor replay, run_id filtering, and type filtering
    • Optional ConcurrencyLimiter integration via :limiter option for run slot acquire/release
    • Task crash handling via Process.monitor with automatic limiter release and awaiter notification
  • SessionSupervisor with DynamicSupervisor and Registry child tree for per-session process lifecycle
  • SessionRegistry with via_tuple/2 and lookup/2 helpers for named registration
  • AmpMockSDK with scenario-based event stream generation for adapter testing without network
  • BlockingTestAdapter for deterministic sequential execution testing
  • RouterTestAdapter with configurable outcomes, sleep/cancel support, and scripted event emission
  • session_runtime.exs, session_subscription.exs, and session_limiter.exs live provider examples
  • Input messages persisted as :message_sent events before adapter execution

Changed

  • SessionStore port now requires append_event_with_sequence/2 and get_latest_sequence/2 callbacks (breaking for custom store implementations)
  • SessionManager routes all event persistence through sequenced appends with monotonic per-session sequence numbers
  • Sequence numbers included in telemetry event data for adapter callback events
  • All three adapters (Claude, Codex, Amp) prepare transcript-aware prompts when session transcript context is present
  • InMemorySessionStore tracks per-session sequence counters with full sequenced event storage and idempotent duplicate detection
  • amp_sdk added as a dependency
  • Existing examples (oneshot, live_session, common_surface, contract_surface_live) updated to support the amp provider
  • run_all.sh refactored with argument parsing, --provider filtering, and run plan display

Documentation

  • Add guides/cursor_streaming_and_migration.md with migration checklist for custom stores
  • Add guides/session_continuity.md and guides/workspace_snapshots.md
  • Add guides/provider_routing.md and guides/policy_enforcement.md
  • Add guides/session_server_runtime.md and guides/session_server_subscriptions.md
  • Update guides/architecture.md module map with all new subsystems (routing, policy, workspace, runtime)
  • Update guides/concurrency.md with runtime limiter integration
  • Update guides/events_and_streaming.md with cursor APIs and workspace/policy event types
  • Update guides/sessions_and_runs.md with feature options and sequence assignment
  • Update guides/live_examples.md with all new example scripts
  • Update guides/provider_adapters.md with AmpAdapter documentation
  • Update README.md with SessionServer usage, cursor streaming, continuity, workspace, routing, and policy sections
  • Update examples/README.md for three-provider support and all new examples
  • Add Routing, Policy, Runtime, and Workspace modules to HexDocs group listings and extras menu
  • Bump installation snippets in README.md and guides/getting_started.md to ~> 0.5.0

0.4.1 - 2026-02-06

Changed

  • Harden adapter execution lifecycle in Claude and Codex adapters by replacing linked worker processes with supervised Task.Supervisor.async_nolink/2 tasks
  • Add deterministic task result and :DOWN handling so adapter calls always resolve with tuple results, including worker-failure paths
  • Fix concurrent execution reply routing to avoid reply loss when run IDs collide
  • Standardize adapter cancellation success return shape to {:ok, run_id} and align control operations with this contract
  • Normalize ControlOperations.interrupt/2 to use provider cancel/2 semantics, avoiding unsafe provider-specific interrupt calls
  • Remove Process.whereis check-then-act dispatch race in ProviderAdapter and use call-first fallback behavior on :noproc
  • Replace dynamic atom creation in core deserialization paths with safe existing-atom conversion via shared serialization utilities
  • Expand Core.Error taxonomy for stream/state mismatch cases (:stream_closed, :context_mismatch, :invalid_cursor, :session_mismatch, :run_mismatch)

Added

  • A shared core serialization utility for safe key conversion and map helpers
  • Serialization safety tests and adapter worker-failure isolation tests

Documentation

  • Update provider and architecture guides to document supervised nolink adapter task execution model
  • Document interrupt-to-cancel behavior in the concurrency guide
  • Bump installation snippets in README.md and guides/getting_started.md to ~> 0.4.1

0.4.0 - 2026-02-06

Changed

  • Ensure adapter execute/4 results include emitted execution events in result.events for both Claude and Codex adapters
  • Ensure Claude :run_completed events include token_usage on both streaming and ClaudeAgentSDK query execution paths
  • Normalize adapter callback event aliases (for example "run_start", "delta", "run_end") to canonical Event.type values before persistence in SessionManager
  • Update SessionManager telemetry emission to use normalized event types on ingest
  • Bump codex_sdk dependency from ~> 0.7.1 to ~> 0.7.2

Added

  • New live example: examples/contract_surface_live.exs to verify runtime contract guarantees across Claude and Codex
  • New live example test: test/examples/contract_surface_live_test.exs
  • New guide: guides/live_examples.md
  • Add live contract-surface example runs to examples/run_all.sh
  • Add HexDocs extras/menu entry for guides/live_examples.md

Documentation

  • Update README.md and guides/getting_started.md dependency snippets to ~> 0.4.0
  • Remove stale mock-mode example commands from top-level docs and guide snippets
  • Expand provider/events docs to reflect current execute/4 events contract and ingest normalization behavior

0.3.0 - 2026-02-06

Changed

  • Switch ClaudeAdapter from ClaudeAgentSDK.Query.run/3 to ClaudeAgentSDK.Streaming for real token-level streaming deltas
  • Simplify event mapping: replace content_block_start/delta/stop with text_delta and tool_use_start events
  • Change default model from claude-sonnet-4-20250514 to claude-haiku-4-5-20251001
  • Add tools option passthrough to ClaudeAdapter start_link/1 and SDK options
  • Set max_turns: 1 in SDK options for single-turn execution
  • Update oneshot example to stream content deltas to stdout instead of progress dots to stderr
  • Bump claude_agent_sdk dependency from ~> 0.10.0 to ~> 0.11.0
  • Bump codex_sdk dependency from ~> 0.6.0 to ~> 0.7.1

0.2.1 - 2026-02-05

Changed

  • Bump claude_agent_sdk dependency from ~> 0.9.2 to ~> 0.10.0

0.2.0 - 2026-02-05

Added

  • SessionManager.run_once/4 convenience function that collapses the full session lifecycle (create, activate, start run, execute, complete/fail) into a single call
  • execute_run/4 now accepts an :event_callback option for real-time event streaming alongside internal persistence
  • examples/oneshot.exs one-shot execution example using run_once/4

0.1.1 - 2026-01-27

Added

  • AgentSessionManager.Config module for centralized configuration with process-local overrides
  • Process-local configuration layering (process dictionary -> application env -> built-in default)
  • Process isolation test for Telemetry.set_enabled/1
  • common_surface.exs example demonstrating provider-agnostic SessionManager lifecycle
  • claude_direct.exs example demonstrating Claude-specific SDK features (Orchestrator, Streaming, Hooks, Agent profiles)
  • codex_direct.exs example demonstrating Codex-specific SDK features (Threads, Options, Sessions)
  • Tests for all new example scripts (common_surface_test.exs, claude_direct_test.exs, codex_direct_test.exs)
  • Configuration guide (guides/configuration.md) documenting the layered config system

Changed

  • AuditLogger.set_enabled/1 now sets a process-local override instead of mutating global application env
  • Telemetry.set_enabled/1 now sets a process-local override instead of mutating global application env
  • AuditLogger.enabled?/0 and Telemetry.enabled?/0 now resolve through AgentSessionManager.Config.get/1
  • Telemetry tests run with async: true (previously async: false due to global state mutation)
  • Telemetry refute_event helper now filters by session_id to avoid false failures from concurrent tests
  • Standardized test process cleanup using cleanup_on_exit/1 from Supertester, replacing manual on_exit blocks
  • Updated examples/run_all.sh to include the new example scripts
  • Updated examples/README.md with documentation for all new examples

0.1.0 - 2026-01-27

Added

  • Initial project setup
  • Basic project structure with mix.exs configuration
  • Project logo and assets