# Changelog

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

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **PTC-Lisp ISO-8601 instant parsing** — the `parse` builtin (also
  reachable as `LocalDate/parse` or the new `Instant/parse` namespace
  alias) now auto-dispatches on the string shape: `YYYY-MM-DD` → `Date`,
  a string with a time component (`...T...`) → `DateTime`. An offset
  (`Z`, `+02:00`, …) is honoured and an offsetless date-time is treated
  as UTC; `.isBefore` / `.isAfter` / `.getTime` work on the result.
  Previously `(parse "2026-01-01T00:00:00Z")` raised a type error. This
  is a deliberate divergence from Java's strict `LocalDate.parse` (which
  rejects time components) — see `docs/java-interop.md`. Closes #885.

- **PTC-Lisp bitwise operations** — `bit-and`, `bit-or`, `bit-xor`,
  `bit-and-not`, `bit-not`, `bit-shift-left`, `bit-shift-right`,
  `bit-clear`, `bit-set`, `bit-flip`, and `bit-test` are now available
  (integers only; non-integer arguments raise a clean PTC-Lisp type
  error rather than an Erlang `ArithmeticError`). The first three plus
  `bit-and-not` are variadic. BEAM integers are arbitrary-precision
  two's-complement, so — unlike Clojure/JVM — the shift amount is not
  taken modulo 64 and a left shift can grow without bound;
  `unsigned-bit-shift-right` is intentionally not provided because it
  has no defined meaning without a fixed integer width. Closes #825.

- **PTC-Lisp `list` builtin** — `(list & args)` is now available as an alias
  for `vector`, returning a vector (PTC-Lisp has no separate list type). This
  matches LLM Clojure training data and removes a recurring `list`/`cons`
  error class at zero prompt cost (`cons` was already supported). Documented
  as DIV-25 in `docs/clojure-conformance-gaps.md`. Closes #779.

- **PTC-Lisp MCP call result contract** — `(tool/mcp-call ...)` now
  returns tagged data directly: `{:ok true :value payload
  :value_kind :json|:text|:none}` for successful calls, or `{:ok false
  :reason kw :message text}` for recoverable upstream/tool failures.
  `mcp/text` and `mcp/json` are no longer exposed; use `(:value r)` after
  checking `(:ok r)`.

- **PTC-Lisp JSON builtins** — `(json/parse-string s)` and
  `(json/generate-string v)` are now available unconditionally in every
  PTC-Lisp run (default mode and aggregator mode alike). Cheshire-shaped
  signatures: parse decodes JSON to Elixir values with **string** map
  keys (no atom keys); encode runs a pre-validation walk before
  invoking `Jason.encode/1` and rejects atoms outside `true/false/nil`,
  atom-keyed maps, tuples, PIDs, references, and functions by returning
  `nil` rather than silently coercing them. Both functions follow the
  DIV-* convention and **never raise** — failures surface as `nil` so
  programs without try/catch can guard cleanly. Documented under
  `docs/clojure-conformance-gaps.md` as DIV-23 and DIV-24, and in
  `Plans/json-support.md` §4. Cheshire users get an analyzer redirect:
  `(cheshire.core/parse-string ...)` now points at `json/parse-string`.

- `KeyNormalizer.canonical_cache_key/2` — deterministic, layer-agnostic
  cache key for tool-result caching. Normalizes map keys to strings,
  recurses through nested maps/lists/tuples, and collapses integer-equal
  floats to integers so semantically identical calls share one cache
  entry regardless of how the args arrived. PTC-Lisp's `(tool/...)` cache
  path now keys via this function (`lib/ptc_runner/lisp/eval.ex`); native
  app-tool calls (Tier 2b) will share the same key. See
  `Plans/text-mode-ptc-compute-tool.md` "Canonical Cache Key —
  Implementation Rule." This is a deliberate cache-compatibility
  migration: equivalence classes are widened (atom/string keys converge,
  map ordering stabilizes, `1` and `1.0` collapse). Value semantics are
  preserved for ordinary callers; only old cache-miss quirks change.

- `compaction:` option for pressure-triggered context compaction. Opt-in
  (default: `false`); only fires for multi-turn agents (`max_turns > 1`) once
  turn count or estimated token usage crosses the configured threshold. Phase 1
  ships the `:trim` strategy; `:summarize` and custom strategy modules are
  deferred to a follow-up. Compaction stats surface on `step.usage.compaction`.
  See `docs/guides/subagent-compaction.md`.

### Fixed

- **PTC-Lisp: no more leaked Elixir internals in type errors** (#862) —
  calling a collection op with the collection and predicate swapped
  (e.g. `(filter [1 2 3] (fn [x] true))`) no longer surfaces a raw
  `protocol Enumerable not implemented for Function, only anonymous
  functions of arity 2 ...`; it now reports `expected a collection, got
  a function — ... arguments may be swapped`. `(get key map)` with the
  arguments swapped now suggests the correct `(get map key)` order
  instead of `get: invalid argument types: keyword, map`. A builtin
  used as a value (e.g. `(first filter)`) now renders as type
  `function` rather than the leaky `unknown`.

### Removed

- Remove the underscore-prefix context firewall convention. `_`-prefixed keys
  are now ordinary visible fields in prompt inventories, formatting, execution
  history, signatures, and namespace export. Addresses H5 from #987.

## [0.10.1] - 2026-05-04

### Fixed

- `count`, `reduce`, and `assoc` now treat `nil` as an empty collection, matching the nil-tolerance of other collection helpers (#863)

### Changed

- Lockfile refresh: `req_llm` 1.8.0 → 1.10.0 (constraint stays at `~> 1.8`, no consumer action needed)
- Dev tooling bumps: `credo` 1.7.18, `usage_rules` 1.2.6

## [0.10.0] - 2026-03-26

### Breaking Changes

- **MetaPlanner, PlanExecutor, PlanRunner, PlanTracer, PlanCritic removed** — The autonomous planning system with JSON task graphs, verification predicates, and replanning has been removed. Use [Composition Patterns](docs/guides/subagent-patterns.md) (`with` chains, `Task.async_stream`, subagents-as-tools) for orchestration instead.
- Planning prompt templates removed (`planning-examples.md`, `verification-predicate-guide.md`, `verification-predicate-reminder.md`, `signature-guide.md`)
- PlanExecutor telemetry events removed
- Internal `llm_client` package removed — use `PtcRunner.LLM` behaviour directly
- **`plan:` no longer auto-enables `journaling: true`** — Plans are now display-only labels for progress visibility. To use journaled task caching, set `journaling: true` explicitly.

### Added

**Model String Shorthand**

- Accept model strings directly in `SubAgent.run` — e.g., `llm: "haiku"` instead of building an LLM struct

**Clojure Conformance Expansion (~30 new functions/forms)**

- Control flow: `case`, `condp`
- HOF combinators: `comp`, `partial`, `complement`, `constantly`, `every-pred`, `some-fn`
- Collection operations: `cons`, `disj`, `empty`, `merge-with`, `reduce-kv`, `zipmap`, `filterv`, `update-keys`, `peek`, `pop`, `subvec`
- Sequence operations: `split-at`, `split-with`, `partition-by`, `dedupe`, `keep`, `keep-indexed`
- String/coercion: `format`, `name`, `keyword`, `hash-map`
- Type predicates: `int?`, `integer?`, `double?`, `float?`, `fn?`, `false?`, `true?`, `symbol?`, `decimal?`, `ratio?`, `rational?`, `nat-int?`, `neg-int?`, `pos-int?`, `infinite?`, `NaN?`
- Collection capability predicates (`sequential?`, `associative?`, `counted?`, etc.)
- Named fn for self-recursion (`(fn name [x] ...)`)
- `%&` rest args in `#()` short function syntax
- Keyword args via rest destructuring (`[& {:keys [a]}]`)
- `:strs` map destructuring for string-keyed maps
- `def`/`defn`/`defonce` can shadow builtins (Clojure-compatible)

**Java Interop Methods**

- String: `.startsWith`, `.endsWith`, `.toLowerCase`, `.toUpperCase`, `.contains`
- Date/DateTime: `.isBefore`, `.isAfter`

**Prompt System**

- 2-axis composable prompt architecture for flexible prompt composition
- Language reference included in default prompt compositions
- Pluggable `progress_fn` for custom turn feedback rendering

**Tracing**

- JSONL trace format v2 with flat event envelope
- Typed trace headers (`trace_kind`, `producer`, `query`, `model`, `trace_label`)
- Trace analyzer agent for investigating execution traces
- Streaming `query_events` and `aggregate_events` tools

### Fixed

- `keys`/`vals` nil-tolerant (like other collection helpers)
- `concat` type error diagnostics for non-collection args
- Hyphen/underscore normalization in flex_access lookups
- `and` returns last truthy value instead of boolean (Clojure conformance)
- `some` with keyword pred returns extracted value, not boolean
- `defn` inside `let` now visible across program expressions
- Code fence parsing uses line-by-line parser instead of regex
- Runtime exceptions classified as `:runtime_error` not `:tool_error`
- Sandbox-safe `list_traces` with bounded head/tail reads

### Changed

- Progress checklist renders for any agent with a `plan:`, regardless of `journaling:` setting
- `step-done` instruction text updated to reflect it is optional
- Bumped `req_llm` to `~> 1.8`

## [0.9.0] - 2026-02-27

### Added

- `SubAgent.chat/3` for multi-turn chat with conversation history threading
- `on_chunk` streaming callback for real-time token-by-token output in text mode
- `PtcRunner.LLM` behaviour with `call/2` and optional `stream/2` callbacks
- `PtcRunner.LLM.callback/2` convenience API with built-in ReqLLM adapter
- Graceful streaming degradation — `on_chunk` fires once with full content when adapter doesn't support streaming

### Documentation

- LLM Setup guide with provider configuration, streaming, custom adapters, and framework integration
- Phoenix Streaming guide for LiveView integration with `chat/3` and `on_chunk`
- Structured Output Callbacks guide for implementing LLM callbacks
- Added phoenix-streaming and structured-output-callbacks guides to ExDoc
- Updated getting-started guide with chat, streaming, and LLM adapter sections

## [0.8.0] - 2026-02-25

### Breaking Changes

- Renamed JSON mode to text mode — `:json` and `:tool_calling` unified into single `:text` output mode
- Removed backward compatibility shims for old mode names
- Renamed builtin tool names to match new text mode conventions
- Migrated system prompts from markdown headings to XML tags
- Removed `gpt-nano` and `gpt-mini` model entries from LLM registry

### Added

**Unified Text Mode**

- `TextMode` module replacing `JsonMode`, with separate `JsonHandler` for structured output
- Native tool calling mode for smaller LLMs that support API-level tool use
- `ToolSchema` module for generating tool schemas from signatures
- Guard against nil `assistant_content` in tool-call messages

**PTC-Lisp Enhancements**

- `defonce` special form for idempotent variable initialization
- `pr-str` function for readable string representation
- `#"..."` regex literal support
- `CoreToSource` module for Core AST to PTC-Lisp source serialization
- MapSet support for `some`, `every?`, `not-any?`, `join`, `split`, `replace`
- Preserved `tool_calls` and `prints` from inside HOF closures
- Preserved `tool_calls` and `tool_cache` across `loop`/`recur` iterations
- Handle `:var` nodes in `SymbolCounter`
- Handle `#'name` var reader syntax in analyzer
- Handle `defonce` in `collect_undefined_vars` static analysis
- Skip bare vars in `or` during static undefined-var analysis
- Treat unbound vars as nil in `or` for safe memory defaults
- `str` fixed to use Clojure syntax for collections
- Return nil for keyword lookup on non-map types (Clojure conformance)

**SubAgent Improvements**

- `max_tool_calls` limit to prevent runaway tool loops
- `pmap_max_concurrency` config to control parallel task limits
- SubAgent `name` propagated to `Step` for TraceTree and Debug display
- Journal/step-done prompt sections gated behind `journaling: true`
- Moved `defonce` docs from base prompt to multi-turn addon

**LLM Client**

- `embed/2,3` and `embed!/2,3` for embedding API support
- Groq provider support
- Bedrock inference profile support
- Migrated to ReqLLM pricing (removed `LLMClient.calculate_cost`)

**Tracing & Viewer**

- Plan progress display in `Debug` and `TraceTree`
- ptc_viewer: multi-run span tree layout styles
- ptc_viewer: collapse span tree groups by default with count badges
- ptc_viewer: draggable sidebar resizer and preserved scroll position
- Trace sanitize `max_map_size` limit to prevent heap overflow

**Examples**

- ALMA: evolutionary memory design for GraphWorld and ALFWorld environments
- ALMA: domain-blind `Environment` behaviour with multi-env support
- ALMA: vector store with cosine similarity and real embeddings
- ALMA: grep-based DebugAgent with ptc_viewer drill-in
- RLM recursive: `pmap_max_concurrency` tuning and LCM-inspired directions

### Changed

- Consolidated `gpt-oss` registry entries to 120B only
- Simplified planner livebook to two-role pattern, dropped reviewer
- Simplified README Calculator example to use auto-extracted signatures
- Bumped `credo` 1.7.15 → 1.7.16
- Bumped `req_llm` 1.2.0 → 1.5.1

### Fixed

- Skip structs in `KeyNormalizer.normalize_keys`
- Include `raw_response` in `turn.stop` telemetry for parse errors
- Add agent names to joke workflow livebook for better trace display

## [0.7.0] - 2026-02-12

### Breaking Changes

- Removed PTC-JSON language entirely (PTC-Lisp only)
- Removed `CapabilityRegistry` module (no proven use case yet)
- Removed redundant JSON CLI and `LispAgent` shim
- Renamed `return_retries` to `retry_turns`

### Added

**Plan System & Multi-Agent Orchestration**

- Plan system with `PlanRunner` and `PlanExecutor` for multi-agent workflows
- `MetaPlanner` with trial & error replanning and replan-on-failure
- Per-task quality gates with evidence-based verification and telemetry
- Direct agent for LLM-free task execution
- Upstream dependency result injection into task prompts
- `--plan-only` / `--plan` CLI flags and Lisp syntax validation for plans

**Journaled Task System**

- `(task "id" expr)` — idempotent journaled execution with journal-based caching
- Dynamic expressions as task IDs
- `step-done` and `task-reset` forms with plan progress tracking
- Journal preserved on error paths

**PTC-Lisp Enhancements**

- Tree traversal functions: `walk`, `prewalk`, `postwalk`, `tree-seq`
- `boolean` and `type` built-in functions
- `:when`, `:let`, `:while` modifiers for `for` and `doseq`
- Map support for `take`, `drop`, and `distinct` family
- Extended keyword chars for operator keywords (Clojure conformance)
- `index-of` and `last-index-of` string builtins

**Tracing & Observability**

- `ptc_viewer` web UI with interactive DAG graph visualization
- Gantt timeline for `pmap` parallel execution in trace viewer
- Expandable execution tree for recursive traces
- Turn pill badges and timeline overview
- Cross-process trace propagation via `TraceContext` module
- `PlanTracer` for plan-layer telemetry (phases, inputs, replan events)
- Trace result preview increased to 64KB
- `trace.stop` event with total duration on collector stop

**SubAgent Improvements**

- `thinking` option for SubAgent and demo CLI
- Configurable sandbox timeout and heap limits via application env
- Unified `builtin_tools` option (replaced `grep_tools`)
- Tool result caching and `child_steps` accumulation
- Pre-execution checks for undefined vars and unknown tools
- Prompt caching support for Anthropic, OpenRouter, and Bedrock

**Examples & Documentation**

- `page_index` example for hierarchical document retrieval with benchmarks
- `supply_watchdog` example project
- Meta Planner guide, Navigator guide, observability guide
- Plan-and-execute livebook and capability registry livebook

### Changed

- Centralized builtin tool injection into `SubAgent.effective_tools/1`
- Replaced `find_undefined_vars` with `Lisp.validate/1`
- Extracted `TraceContext` module for centralized trace propagation
- Refactored to use `Prompts` module for SubAgent loop
- Simplified `LanguageSpec` to use `Prompts` module
- Explicitly set `output: :ptc_lisp` in `PlanRunner`
- Bumped `req_llm` 1.2.0 → 1.5.1

### Fixed

- Prevented LLM thinking text from polluting message history
- Fixed XML-style `</clojure>` closers in code block parsing
- Made `grep` always-regex with BRE-to-PCRE auto-translation
- Hardened tracing reliability and removed duplicate tool telemetry
- Prevented `println`+`return` same turn conflict
- Fixed `(str x)` to convert single non-string arg to string
- Fixed false positive on `#"` check inside string literals
- Routed task failures to replan when `max_total_replans > 0`
- Prevented `TraceLog.Collector` crash when parent task is killed
- Collected child Steps on parent Step for TraceTree hierarchy
- Added named-arg usage example to tool signatures to prevent positional arg errors
- Scoped turn lookup by `span_id` to prevent cross-agent collisions in viewer
- Resolved dialyzer errors in linker and plan_executor

## [0.6.0] - 2026-01-30

### Added

**Language**

- `for` (minimal) list comprehension
- String functions: `.indexOf`, `.lastIndexOf`
- `builtin_tools` option for injecting builtin tools (e.g., `grep`, `grep-n`) instead of hardcoded builtins
- Collection functions: `extract`, `extract-int`, `pairs`, `combinations`, `mapcat`, `butlast`, `take-last`, `drop-last`, `partition-all`
- Aggregators: `sum`, `avg`, `quot`
- Reader literals: `##Inf`, `##-Inf`, `##NaN`

**SubAgent**

- `return_retries` for validation recovery with compression support
- `:self` sentinel for recursive agents
- `memory_strategy :rollback` for recoverable memory limit errors
- Budget introspection and callback for RLM patterns
- Last expression as return value on budget exhaustion
- `llm_query` builtin integrated into system prompts and tool normalization
- Auto-set `return_retries` for agents with tools during compile

**LLM-as-Tool Composition**

- `LLMTool` with `response_template` mode for typed LLM output
- Transparent tool unwrapping and input validation

**Tracing & Observability**

- `TraceLog` + `Analyzer` for structured SubAgent tracing
- Hierarchical tracing for nested SubAgents
- Chrome DevTools trace export
- HTML trace viewer
- Post-sandbox tool telemetry with span correlation

**Utilities**

- `PtcRunner.Chunker` for text chunking
- Configurable `pmap_timeout` for LLM-backed tools

### Changed

- Refactored SubAgent loop from recursive to iterative driver loop
- Extracted chaining, validation, and prompt modules into focused files

### Fixed

- Propagate `max_heap` option to Lisp.run and child agents
- Handle tool call positional args error gracefully
- Support `apply` with maps and variadic `max-by`/`min-by`

## [0.5.2] - 2026-01-23

### Added

- **Mustache Templates** - Standalone `PtcRunner.Mustache` module for template rendering (#719)
- **Unified SubAgent API** - CompiledAgent support with `then/3` for chaining (#709)
- Support `timeout` and `max_heap` options in compiled agent execution
- Allow SubAgentTools in compiled agents
- JSON reports with failure traces for demo benchmarks
- Signature naming convention documentation (underscores vs hyphens)
- Improved signature documentation and error messages (#715)

### Fixed

- Normalize hyphenated keys to underscores at tool boundary (#706)
- Enforce named args and string keys at tool boundary
- Normalize keys in `has_keys` constraint for better prompt clarity
- Return error for non-scalar Mustache variable expansion
- Use string keys for JSON mode and add `max_turns` for compile
- Allow `timeout` option in string convenience form
- Fix report filename extraction for Bedrock model IDs

## [0.5.1] - 2026-01-18

### Added

- **JSON Output Mode** - SubAgents can now return structured JSON instead of PTC-Lisp
  - Add `output:` field to SubAgent struct for declaring JSON schema
  - Add `Signature.to_json_schema/1` for JSON schema generation
  - Add `LLMClient.generate_object/4` for structured output generation
  - Add `LLMClient.callback/1` for SubAgent integration
  - Support array types and improved validation UX
- Add `re-seq` regex function to PTC-Lisp for extracting all matches
- Add debug mission display and tool call statistics with Clojure format output

### Fixed

- Convert keyword-style tool args to map in Lisp interpreter

## [0.5.0] - 2026-01-16

### Breaking Changes

- Replace `ctx/` namespace with `data/` and `tool/` namespaces for clearer separation
- Remove `tool_catalog` field from SubAgent (use `tools` directly)

### Added

**Observability & Message History (v0.5 theme)**

- Add `Turn` struct for immutable per-turn execution history with tool calls, prints, and memory snapshots
- Add `SingleUserCoalesced` compression strategy for token-efficient multi-turn conversations
- Add `compression: true` option to enable message compression in SubAgent
- Add `collect_messages: true` option to capture full conversation history
- Enhance `print_trace/2` with new options: `view: :compressed`, `messages: true`, `raw: true`, `usage: true`
- Add compression statistics to debug output
- Add prompt caching support by splitting static/dynamic sections

**New Functions**

- Add `distinct-by` for unique items by key function
- Add `re-split` for regex-based string splitting
- Add `rem` function and fix `mod` to match Clojure semantics
- Add multi-arity `map` and `partition` functions
- Add list index support to `get-in`, `assoc`, `update`, and related functions
- Add context filtering via static analysis to reduce memory pressure

**Other**

- Add configurable println truncation limit (`max_print_length` option)
- Add hidden fields filtering from LLM-visible output (fields starting with `_`)
- Add configurable sample limits and smart println for char lists
- Improve float support in PTC-Lisp

### Fixed

- Multi-arity map with variadic builtins
- Propagate `max_print_length` into closures and pcalls
- Show map field names in tool signatures for LLM
- Handle nil values in `Debug.print_trace` options
- Support builtin tuples in `fnil` for Clojure compatibility
- Show explicit "No tools available" message in prompt

## [0.4.1] - 2026-01-09

### Added

- Add `juxt` function combinator for multi-criteria operations
- Add variadic function support with rest parameters `[a & rest]`
- Add `max-key` and `min-key` for variadic comparisons
- Add IEEE 754 special values: `##Inf`, `##-Inf`, `##NaN`
- Add `float_precision` option to SubAgent (default: 2 decimal places)
- Add `context_descriptions` for automatic data inventory in prompts
- Extend `reduce` to work on maps, sets, and strings
- Add variadic `update` and `update-in` (match Clojure semantics)
- Add `java.time.LocalDate/parse` for date handling

### Fixed

- Preserve memory state on parse/analysis errors (multi-turn recovery)
- Handle `return`/`fail` correctly in threading macros (`->`, `->>`)
- Make `return`/`fail` terminate execution immediately
- Restore caller environment after closure execution
- Improve error messages with actionable suggestions

## [0.4.0] - 2026-01-06

### Added

- Add SubAgent API for high-level agent definition with type-safe signatures, auto-chaining, and resource limits
- Add Tracer system for immutable recording and visualization of agent execution
- Implement loop and recur support for iterative computation in PTC-Lisp
- Add character literals and string-as-sequence support for more flexible data handling
- Add `pcalls` for parallel execution of heterogeneous thunks
- Add `pmap` for parallel map evaluation
- Support vector paths in collection extraction functions for nested data access
- Add Clojure namespace normalization to improve LLM resilience

### Fixed

- Correct argument order for sort-by function to match Clojure semantics
- Fix update-vals argument order to match Clojure 1.11
- Update supported functions list (add frequencies, add float and for)
- Improve multi-turn agent guidance and system prompts
- Add specific error messages for predicate functions
- Fix Clojure compatibility for destructuring, count, and empty?

## [0.3.4] - 2025-12-25

### Added

- Add seqable map support to filter, remove, and sort-by operations
- Add entries and identity functions to PTC-Lisp
- Add sandbox support to PtcRunner.Lisp for resource limits

### Fixed

- Replace length() comparisons with Enum.empty? alternative
- Update error handling to use error tuples instead of raised exceptions

## [0.3.3] - 2025-12-22

### Added

- Add `update` and `update-in` map bindings for transforming values with functions
- Add function-based key support to `*-by` operations for custom sorting and grouping
- Add spec validation system for PTC-Lisp with multi-line examples and section reporting
- Improve JSON DSL prompts for better LLM accuracy

### Fixed

- Fix JSON agent to retry on empty LLM responses
- Improve deterministic ordering in keys/vals output
- Align `assoc-in` and `update-in` with Clojure semantics for intermediate path creation
- Correct `update/3` semantics to pass nil to function for missing keys
- Fix zip and into operations to return vectors instead of tuples
- Handle empty and nil LLM responses gracefully in agent loop

## [0.3.2] - 2025-12-20

### Added

- Add format_error/1 for human-readable error messages

### Fixed

- Include ptc-lisp-llm-guide.md in hex package

## [0.3.1] - 2025-12-13

### Added

- Improve PTC-JSON system prompt for better LLM accuracy
- Add object operation to construct maps with evaluated values (#253) (#254) ([#254](https://github.com/andreasronge/ptc_runner/pull/254))
- Enhance Clojure validation to execute and compare results
- Add auto-generated report filenames and reports directory
- Add cross-dataset join test case and clean up old reports
- Add --show-prompt option to display system prompts
- Add arithmetic operations (add, sub, mul, div, round, pct) #255
- Add membership operations (in, filter_in) (#257) (#259) ([#259](https://github.com/andreasronge/ptc_runner/pull/259))
- Add implicit object literals for memory storage (#256) (#261) ([#261](https://github.com/andreasronge/ptc_runner/pull/261))

### Fixed

- Handle Map values in constraint errors and fix GenServer timeout
- Correct round operation documentation for precision constraints
- Improve LLM prompt with arithmetic ops and better examples
- Evaluate filter_in value when it's a DSL expression
- Add sort_by order:desc to LLM prompt

## [0.3.0] - 2025-12-11

### Added

- Add PTC-Lisp LLM generation benchmark (Phase 1)
- Improve generation and judge prompts for PTC-Lisp benchmark
- Improve benchmark with edge cases, better judge, and dry run output
- Add autonomous issue creation and GitHub Project integration to PM workflow
- Enhance PM workflow with tech debt priority and efficiency fixes
- Auto-trigger implementation on ready-for-implementation label
- Auto-trigger code review for PRs from claude/* branches
- Install git pre-commit hook in Claude workflow
- Create PtcRunner.Json public API and deprecate PtcRunner (#103) ([#103](https://github.com/andreasronge/ptc_runner/pull/103))
- Allow full Bash access in claude.yml workflow
- Implement PTC-Lisp parser infrastructure (Phase 1) - Closes #106 (#107) ([#107](https://github.com/andreasronge/ptc_runner/pull/107))
- Implement PTC-Lisp analyzer infrastructure (Phase 2) - Closes #108 (#109) ([#109](https://github.com/andreasronge/ptc_runner/pull/109))
- Implement PTC-Lisp eval infrastructure (Phase 1) - Closes #111 (#112) ([#112](https://github.com/andreasronge/ptc_runner/pull/112))
- Implement PtcRunner.Lisp entry point with memory contract - Closes #115 (#116) ([#116](https://github.com/andreasronge/ptc_runner/pull/116))
- Add hourly schedule trigger to PM workflow
- Add pre-computed phase status to PM workflow prompt
- Implement LispGenerators module with StreamData generators (#130) (#132) ([#132](https://github.com/andreasronge/ptc_runner/pull/132))
- Add property tests for evaluation safety and determinism (#133) (#134) ([#134](https://github.com/andreasronge/ptc_runner/pull/134))
- Add domain property tests for arithmetic, collections, types, and logic (#135) (#136) ([#136](https://github.com/andreasronge/ptc_runner/pull/136))
- Support flexible key access in where clause field accessors (#137) (#138) ([#138](https://github.com/andreasronge/ptc_runner/pull/138))
- Add Lisp.Schema module and extend Runtime with flexible key access (#139) ([#139](https://github.com/andreasronge/ptc_runner/pull/139))
- Add truncation hints to guide LLM query refinement
- Add PTC-Lisp CLI and enhance demo infrastructure
- Refactor PM workflow to use Epic Issue pattern
- Add LispTestRunner and improve multi-turn support
- Add file size analysis to PR review workflow
- Add #{...} set literal syntax support (Phase 1 of #164) (#166) ([#166](https://github.com/andreasronge/ptc_runner/pull/166))
- Add {:set, [t()]} to AST type specifications (#167) (#168) ([#168](https://github.com/andreasronge/ptc_runner/pull/168))
- Add set analysis support (Phase 3 of #164) (#170) ([#170](https://github.com/andreasronge/ptc_runner/pull/170))
- Add set evaluation support (Phase 4 of #164) (#172) ([#172](https://github.com/andreasronge/ptc_runner/pull/172))
- Add .env support and model selection for e2e tests
- Add flex_fetch/2 and flex_get_in/2 to Runtime module (#188) ([#188](https://github.com/andreasronge/ptc_runner/pull/188))
- Add update-vals for map value transformation
- Create TestRunner.Base with shared constraint/formatting functions (#197) ([#197](https://github.com/andreasronge/ptc_runner/pull/197))
- Create TestRunner.Report with markdown generation (#199) ([#199](https://github.com/andreasronge/ptc_runner/pull/199))
- Create TestRunner.TestCase with shared test definitions (#201) ([#201](https://github.com/andreasronge/ptc_runner/pull/201))
- Create CLIBase with shared CLI utilities (#203) ([#203](https://github.com/andreasronge/ptc_runner/pull/203))
- Set up demo test infrastructure (MockAgent, test config) - Closes #205 (#206) ([#206](https://github.com/andreasronge/ptc_runner/pull/206))
- Create JsonTestRunner with shared modules support
- Create JsonCLI module with test mode support (#217) ([#217](https://github.com/andreasronge/ptc_runner/pull/217))
- Add memory support to JSON Agent (#220) (#221) ([#221](https://github.com/andreasronge/ptc_runner/pull/221))
- Add agent injection to test runners for MockAgent testing (#222) (#223) ([#223](https://github.com/andreasronge/ptc_runner/pull/223))
- Add ModelRegistry and unify test cases (#227) ([#227](https://github.com/andreasronge/ptc_runner/pull/227))
- Add --runs=N option for running tests multiple times
- Add keyword/string type coercion to where clause comparisons (#232) (#233) ([#233](https://github.com/andreasronge/ptc_runner/pull/233))
- Align JSON DSL memory model with Lisp (#234)
- Add take, drop, and distinct operations to JSON DSL (#236) (#243) ([#243](https://github.com/andreasronge/ptc_runner/pull/243))
- Add enhanced stats to demo test runner report (#246) (#249) ([#249](https://github.com/andreasronge/ptc_runner/pull/249))

### Fixed

- Move PM prompt to command file to fix expression length limit
- Use Bash(gh:*) pattern for PM workflow
- Trigger PM workflow on claude-approved label too
- Re-trigger code review on sync for claude/* branches
- Use --force in precommit to catch stale .beam files
- Add spec document verification to code review prompt
- Include PR comments and review comments in claude.yml
- Add mkdir permission to claude.yml workflow
- Add explicit Claude CLI install to workaround action bug
- Add safety net to push unpushed commits in PR fix workflow
- Mark PTC-Lisp implementation checklist items as complete (#123) ([#123](https://github.com/andreasronge/ptc_runner/pull/123))
- Update README with PTC-Lisp announcement and API migration guidance
- Complete API migration in Integration with LLMs section
- Implement compile-time extraction for PTC-Lisp schema prompt (#144) ([#144](https://github.com/andreasronge/ptc_runner/pull/144))
- Configure StreamData to run 300 iterations in CI (#146) ([#146](https://github.com/andreasronge/ptc_runner/pull/146))
- Make issue review always update the issue body
- Add sequential destructuring pattern type to CoreAST (#149) ([#149](https://github.com/andreasronge/ptc_runner/pull/149))
- Extend analyze_pattern for vector destructuring patterns
- Complete PR #151 - Add fn parameter destructuring documentation and tests
- Complete PR #151 - Remove stale documentation and add insufficient elements test
- Complete PR #151 - Remove stale documentation and add insufficient elements test
- Add E2E test for group-by with destructuring (#153) ([#153](https://github.com/andreasronge/ptc_runner/pull/153))
- Add analyzer unit tests for fn parameter destructuring patterns (#155) ([#155](https://github.com/andreasronge/ptc_runner/pull/155))
- Add evaluator unit tests for fn parameter destructuring patterns (#157) ([#157](https://github.com/andreasronge/ptc_runner/pull/157))
- Update LLM guide map example to use fn destructuring syntax (#159) ([#159](https://github.com/andreasronge/ptc_runner/pull/159))
- Enable sort-by with comparator and builtin HOF arguments (#160) ([#160](https://github.com/andreasronge/ptc_runner/pull/160))
- Extend multi-arity support to get and get-in (#163) ([#163](https://github.com/andreasronge/ptc_runner/pull/163))
- Unify concurrency groups for Claude issue workflows
- Add MapSet-safe collection operations and set runtime support (#175) ([#175](https://github.com/andreasronge/ptc_runner/pull/175))
- Add set literal formatting support to formatter (Phase 6 of #164) (#178) ([#178](https://github.com/andreasronge/ptc_runner/pull/178))
- Add test coverage for remove, mapv, empty?, and count on sets (#181) ([#181](https://github.com/andreasronge/ptc_runner/pull/181))
- Split eval_test.exs into multiple focused test files (#182) ([#182](https://github.com/andreasronge/ptc_runner/pull/182))
- Extract shared dummy_tool test helper (#183) (#184) ([#184](https://github.com/andreasronge/ptc_runner/pull/184))
- Support string key parameters in Lisp runtime functions (#185) ([#185](https://github.com/andreasronge/ptc_runner/pull/185))
- Standardize OpenAI model to gpt-5.1-codex-mini
- Rename duplicate module name in integration_test.exs
- Wire all call sites to use flex_fetch/flex_get_in for string/atom key interop
- Add integration tests and update docs for flexible key access (Phase 3)
- Update docs for flexible key access implementation
- Add @doc annotation to flex_get for API consistency
- Update ptc-lisp-overview.md to reflect completed flex key access (#192) ([#192](https://github.com/andreasronge/ptc_runner/pull/192))
- Update format_error references to PtcRunner.Json.format_error
- Update CHANGELOG format_error reference
- Change update-vals argument order to match Clojure 1.11
- Remove duplicate incorrect update-vals signature from LLM guide
- Handle FunctionClauseError in builtins with descriptive type errors
- Handle FunctionClauseError in multi-arity functions and complete type error messages
- Delete old TestRunner module and update README references (#219) ([#219](https://github.com/andreasronge/ptc_runner/pull/219))
- Require closing keyword in PR body for auto-close
- Add --report option to Lisp CLI Options table
- Update demo CLI to use ModelRegistry.resolve pattern (#229) ([#229](https://github.com/andreasronge/ptc_runner/pull/229))
- Update guide.md to reflect new JSON DSL API signature
- Update guide.md and demo to use new 4-tuple return format
- Handle invalid map destructuring syntax gracefully in analyzer
- Improve error message for update-vals with swapped arguments
- Update JSON agent to use new memory model API (#235) (#241) ([#241](https://github.com/andreasronge/ptc_runner/pull/241))
- Filter nil opts in CLI to allow Keyword.get defaults
- Split transformation_test.exs into access_test.exs and collection_test.exs (#244) (#247) ([#247](https://github.com/andreasronge/ptc_runner/pull/247))
- Align PTC-Lisp semantics with Clojure specification (#245) (#248) ([#248](https://github.com/andreasronge/ptc_runner/pull/248))
- Resolve remaining Clojure conformance test failures (#250) ([#250](https://github.com/andreasronge/ptc_runner/pull/250))

## [0.2.0] - 2025-12-05

### Added

- Add introspection operations (keys, typeof) to DSL (#92) ([#92](https://github.com/andreasronge/ptc_runner/pull/92))
- Improve DSL consistency for better LLM program generation (#94) ([#94](https://github.com/andreasronge/ptc_runner/pull/94))
- Add explore mode for schema discovery (#97) ([#97](https://github.com/andreasronge/ptc_runner/pull/97))
- Enable async execution for test modules (#98) ([#98](https://github.com/andreasronge/ptc_runner/pull/98))
## [0.1.0] - 2025-12-03

### Added

- Add CI check to verify STATUS.md is updated in PRs
- Implement Phase 1 core interpreter with JSON parsing and sandbox execution (#10) ([#10](https://github.com/andreasronge/ptc_runner/pull/10))
- Add pre-implementation check for blockers in PM workflow
- Implement get operation for nested path access (fixes #17) (#18) ([#18](https://github.com/andreasronge/ptc_runner/pull/18))
- Implement comparison operations (neq, gt, gte, lt, lte) (#22) ([#22](https://github.com/andreasronge/ptc_runner/pull/22))
- Implement collection operations (first, last, nth, reject) (#26) (#27) ([#27](https://github.com/andreasronge/ptc_runner/pull/27))
- Implement contains, avg, min, max operations (#28)
- Implement let variable bindings for Phase 3 (#30) (#31) ([#31](https://github.com/andreasronge/ptc_runner/pull/31))
- Implement if conditional operation for Phase 3 (#32) (#33) ([#33](https://github.com/andreasronge/ptc_runner/pull/33))
- Implement boolean logic operations (and, or, not) for Phase 3 (#34) (#35) ([#35](https://github.com/andreasronge/ptc_runner/pull/35))
- Implement combine operations (merge, concat, zip) for Phase 3 (#37) ([#37](https://github.com/andreasronge/ptc_runner/pull/37))
- Implement call operation for tool invocation (#41) ([#41](https://github.com/andreasronge/ptc_runner/pull/41))
- Add Jaro-Winkler typo suggestions for unknown operations (#44) ([#44](https://github.com/andreasronge/ptc_runner/pull/44))
- Add ExDoc and Hex package metadata (#45) (#46) ([#46](https://github.com/andreasronge/ptc_runner/pull/46))
- Implement declarative schema module for DSL operations (#52) ([#52](https://github.com/andreasronge/ptc_runner/pull/52))
- [Phase 5] JSON Schema Generation (#50) (#55) ([#55](https://github.com/andreasronge/ptc_runner/pull/55))
- [Phase 5] E2E LLM Testing Infrastructure (#51) (#57) ([#57](https://github.com/andreasronge/ptc_runner/pull/57))
- Adopt program wrapper as canonical PTC format - Update to_json_schema/0 (#63) ([#63](https://github.com/andreasronge/ptc_runner/pull/63))
- Adopt program wrapper as canonical PTC format in parser (#58) (#64) ([#64](https://github.com/andreasronge/ptc_runner/pull/64))
- Add structured output support with generate_program_structured! for E2E tests (#65) (#67) ([#67](https://github.com/andreasronge/ptc_runner/pull/67))
- Validate tool function arities at registration time (#42) (#68) ([#68](https://github.com/andreasronge/ptc_runner/pull/68))
- Add interactive demo CLI for PTC with ReqLLM integration (#75) ([#75](https://github.com/andreasronge/ptc_runner/pull/75))
- Add to_prompt/0 for token-efficient LLM text mode (#80) ([#80](https://github.com/andreasronge/ptc_runner/pull/80))
- Add security gates and hardening to Claude workflows

### Fixed

- Add safety improvements to GitHub workflows
- PM workflow commits STATUS.md directly to main
- Avoid parallel PRs by including STATUS.md in implementation PR
- Simplify STATUS.md update rules to prevent merge conflicts
- Improve PM workflow action handling
- Trigger PM workflow when issue becomes ready-for-implementation
- Ensure git push happens immediately after commit in Claude workflow
- Use PAT in issue-review workflow to trigger PM workflow
- Optimize min_list and max_list performance and update avg docs
- Correct documentation for sum vs avg behavior with non-numeric values
- Use anyOf for nested expressions in LLM schema (#71) ([#71](https://github.com/andreasronge/ptc_runner/pull/71))
- Improve LLM schema descriptions and use Haiku 4.5 (#73) ([#73](https://github.com/andreasronge/ptc_runner/pull/73))
- Store last_result in Agent state to avoid regenerating random data (#79) ([#79](https://github.com/andreasronge/ptc_runner/pull/79))
- Add test_coverage configuration to exclude test support modules (#89) ([#89](https://github.com/andreasronge/ptc_runner/pull/89))
[0.9.0]: https://github.com/andreasronge/ptc_runner/compare/v0.8.0...v0.9.0
[0.8.0]: https://github.com/andreasronge/ptc_runner/compare/v0.7.0...v0.8.0
[0.7.0]: https://github.com/andreasronge/ptc_runner/compare/v0.6.0...v0.7.0
[0.6.0]: https://github.com/andreasronge/ptc_runner/compare/v0.5.2...v0.6.0
[0.5.2]: https://github.com/andreasronge/ptc_runner/compare/v0.5.1...v0.5.2
[0.5.1]: https://github.com/andreasronge/ptc_runner/compare/v0.5.0...v0.5.1
[0.5.0]: https://github.com/andreasronge/ptc_runner/compare/v0.4.1...v0.5.0
[0.4.1]: https://github.com/andreasronge/ptc_runner/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/andreasronge/ptc_runner/compare/v0.3.4...v0.4.0
[0.3.4]: https://github.com/andreasronge/ptc_runner/compare/v0.3.3...v0.3.4
[0.3.3]: https://github.com/andreasronge/ptc_runner/compare/v0.3.2...v0.3.3
[0.3.2]: https://github.com/andreasronge/ptc_runner/compare/v0.3.1...v0.3.2
[0.3.1]: https://github.com/andreasronge/ptc_runner/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/andreasronge/ptc_runner/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/andreasronge/ptc_runner/compare/v0.1.0...v0.2.0
