[0.12.0] - 2026-06-03
Breaking Changes
- Renamed the upstream tool Lisp surface from the MCP-specific
(tool/mcp-call ...) and (mcp/servers) forms to transport-neutral
(tool/call ...) and (tool/servers).
- Tightened upstream configuration transport names. Use
"openapi",
"mcp_stdio", or "mcp_http"; older ambiguous names such as "stdio" and
"http" are rejected.
- Corrected several PTC-Lisp edge-case semantics for Clojure conformance,
including find as associative lookup, range type errors, negative nth,
duplicate literal map/set keys, and arity handling for assoc, juxt, and
bitwise helpers.
Added
- Added the root upstream runtime for embedded Elixir callers and
mix ptc.repl,
allowing PTC-Lisp programs to call configured OpenAPI, MCP stdio, and MCP HTTP
upstream tools without running the MCP server.
- Added read-only JSON OpenAPI upstream support with credential bindings,
operation allow-lists, schema loading, response caps, and the same tagged
tool/call result model used for MCP upstreams.
- Added
PtcRunner.Session for embedding stateful REPL-style PTC-Lisp
evaluation with persistent (def ...) memory and bounded *1/*2/*3
result history.
- Added upstream-aware
mix ptc.repl options for loading upstream configs,
listing tools, discovery, call budgets, response caps, and catalog snapshot
modes.
- Added
mission_log_in: :user_message format support so agents can keep system
prompts stable for provider prompt caching.
Changed
- Moved MCP aggregation onto the shared root upstream runtime, so root callers
and the MCP server use the same config format, discovery forms, credential
redaction, and tool/call execution semantics.
- Expanded PTC-Lisp Clojure conformance across nil-tolerant sequence helpers,
multi-collection map/mapv/pmap, variadic interleave, three-arity
nth, seq-form replace, Java Boolean/parseBoolean, and Java Math special
cases.
- Improved release readiness with deterministic smoke, performance, coverage,
docs, and package-content checks.
Fixed
- Authentication is enforced before MCP HTTP method dispatch, required on
non-loopback binds, rate-limited on failed bearer attempts, and scrubbed from
traces/log-facing output.
- Upstream MCP result normalization now returns the first text block rather than
only inspecting the first content item.
- Closed-but-unpruned MCP HTTP sessions now resolve to tombstones instead of
crashing through a missing process.
- Invalid integer HTTP/MCP configuration values now fail fast with clearer
errors.
Release Checks Report
Gate Verdict
READY TO PUBLISH
Failed gating jobs: none
Job Results
| Job |
Result |
Gates publish? |
| test |
success |
yes |
| soak |
success |
yes |
| integrity |
success |
yes |
| docs |
success |
yes |
| perf |
success |
yes |
| llm-smoke |
success |
no |
| stats |
success |
no |
| coverage |
success |
no |
Artifacts
release-fragment-*
release-metrics-* (machine-readable stats/coverage JSON)
release-hex-unpack
release-llm-smoke-reports when the LLM smoke job ran
release-checks-report
- On a tag push: a GitHub Release with these notes +
release-metrics.json attached
coverage
Built-in mix test --cover, measured per project in isolation
(ignore_modules applied where configured).
| Project |
Total line coverage |
Modules measured |
Modules < 50% |
Modules at 0% |
| ptc_runner (library) |
84.2% |
181 |
4 |
1 |
| ptc_runner_mcp (server) |
77.9% |
66 |
0 |
0 |
docs
| Check |
Outcome |
MIX_ENV=dev mix docs --warnings-as-errors |
success |
| Generated-doc drift |
success |
| Lychee offline relative-link gate |
success |
| Lychee online external-link info |
success |
integrity
- Release version:
0.12.0
- Unpacked package:
tmp/hex-unpack
| Check |
Outcome |
| Version/tag and changelog heading |
success |
| Hex package bundled files |
success |
| Schema drift |
success |
| Spec checksums |
success |
llm-smoke
- Model:
openrouter:google/gemini-3.1-flash-lite
- Runs per demo suite:
1
- Gating: non-gating stats only
| Surface |
Passed |
Total |
Pass rate |
Total tokens |
Cost |
| demo Lisp |
30 |
30 |
100.0% |
2074 |
0.0 |
| root e2e |
389 doctests, 3 properties, 5741 tests, 1 failure (329 excluded) |
|
|
|
|
perf
| Command |
Outcome |
MIX_ENV=test mix bench.check |
success |
soak
| Command |
Outcome |
PTC_SOAK_ITERATIONS=3000 MIX_ENV=test mix test --only soak |
success |
cd mcp_server && mix deps.get |
success |
cd mcp_server && PTC_SOAK_ITERATIONS=3000 mix test --only soak test/soak/session_churn_soak_test.exs test/soak/many_turns_soak_test.exs test/soak/http_mcp_soak_test.exs |
success |
stats
Size (v0.12.0)
| Surface |
Files |
LOC |
Modules |
| lib (root) |
180 |
59,206 |
187 |
| test (root) |
240 |
70,059 |
— |
| mcp_server lib |
— |
19,866 |
— |
- Test : code ratio: 1.18 : 1 (70,059 test / 59,206 lib LOC)
- Test cases: 6,025 in 1,310 describe blocks
Growth
Since v0.11.0:
| Metric |
Δ |
| lib LOC |
+4,657 |
| test LOC |
+6,658 |
| test cases |
+566 |
| modules |
+27 |
| commits |
173 |
- Overall diff: 419 files changed, 47791 insertions(+), 44770 deletions(-)
Health
| Metric |
Value |
| @SPEC coverage (specs / public defs) |
29% (557 / 1,931) |
| TODO·FIXME in lib |
10 |
| Largest lib file |
lib/ptc_runner/sub_agent/loop/text_mode.ex (2314) |
| Dependencies (mix.exs) |
15 |
test
| Command |
Outcome |
MIX_ENV=test mix test |
success |