Version 2.2.0 (22/08/2026)
********************
Feature: LLM Connections — a new <llm> / <llmvendor> connection primitive. LLMConnection parses vendor/model configuration into typed errors and a stats struct, connects over the CMSDK HTTP client, and calls an endpoint via interact() with JSON path extraction (jsmn). Both a request/response mode (mode-A) and a streaming mode (mode-B) are supported, with mode-B stream statistics accounting, a typed cancel error, reset() parity and an owner-end lifecycle callback hook
Feature: LLM Connections — real streaming transport. Added an SSEEventParser, an HTTPChunkedDecoder, a StreamByteSource with bounded pump loops, and an EventStreamFrameParser that validates the AWS event-stream prelude and per-message CRCs — so live token-streaming endpoints (SSE and binary event-stream) are consumed correctly
Feature: LLM Connections — secret handling. LLM credentials resolve from environment-variable or file references, and inline secrets in a spec are rejected, so keys never have to live in the spec file
Feature: PsySpace::registerInternalCrank — inject a built-in crank by function name, backing the Root-space Supervisor/Builder cranks on the Psyclone side
Feature: Test — a seeded oracle fuzz for the ProcessMemory ring (test=processmemory_fuzz), a Phase-2 ring-invariant checker, and a resize-heavy op-mix (PSY_RING_RESIZEHEAVY=1)
Feature: Utils — POSIX pseudo-terminal process primitives and utils::ProbeProcessWait, a stall-on-stdin probe (Linux exact, macOS composite, Windows stub), for the Windows stall-probe test work
Fix: Reliable POSIX shared-segment cleanup — startup pre-clean plus graceful unlink, so a killed run can't leave a stale named segment behind to poison the next start
Fix: Launch die-with-parent children from a persistent launcher thread, so a spawned child is reliably torn down with its parent
Fix: NewProcess/NewProcessEx must not treat the command line / title as a printf format string — a % in a command line no longer triggers a Windows c0000409 fast-fail (was crashing the CLIRunner test=cmsdk case)
Fix: POSIX NewProcessEx implemented with capture / env / process-group support and an optional posixUseShell (/bin/sh -c), unified onto a single shared launch path; ReleaseProcessCapture exposed for a signal-free capture-pipe release
Fix: SSL client verification on Windows now imports the Windows ROOT system store (CryptoAPI) into the SSL_CTX X509 store — SSL_CTX_set_default_verify_paths pointed at the build-time OPENSSLDIR and failed cert verification against public endpoints on end-user machines
Fix: HTTP client fixes exposed by the LLMConnection work — honour the computed encryption in makeHTTPRequest (was hardcoded to SSL), un-invert the ReceiveHTTPReply timeout check, preserve a buffered reply when the peer closes after responding (Connection: close), and correct the URL parser (colon-in-path vs port) and chunked transfer-encoding decode
Fix: Fixed a NetworkThread teardown use-after-free race — capture parent/id before clearing isRunning, and have endConnection/shutdown wait (bounded, self/forced-aware) for the worker OS-thread to exit
Fix: NetworkManager map corruption fixed — wrong id space, operator[] on read paths, and missing locking
Fix: PsyAPI::waitForNewMessage held a dangling reference into a popped queue slot
Fix: Memory-safety pass under a new ASan gate — fixed gethostbyname_r use-after-free, ~21 new[]/scalar-delete mismatches, a PsySpace::logEntry leak, 22 StringFormat frees, and a third over-read in GetFirstFreeBitLocN (now word-granular)
Fix: Flake-1 shutdown hardening — cooperative-only connection-worker shutdown (no pthread_cancel of a mutex holder), Node::terminate teardown deadlock fixed with a cancel-safe mutex and a dedicated signal thread, and ThreadManager::JoinThread now joins the worker before freeing the NetworkThread
Fix: Windows portability of the concurrency fuzz TUs — _putenv_s (setenv is POSIX), GetModuleFileNameA on the re-exec path, and a portable temp path instead of a hardcoded /tmp
Build: Added ProcessMemoryFuzz/ConcFuzz and LLMConnection translation units to the vs2022 project/filters so a headless MSBuild links them; dropped stray cmsdk_perf_*.json test artifacts
Build: Scale unit-test time budgets under sanitizers (UT_TIME_SCALE); ignore SIGPIPE so the SSL tests can run
Docs: LLM guide documents the child-process launch path (NewProcessEx, capture lifecycle, ReleaseProcessCapture); the Doxyfile dist-copy exclusion is version-agnostic so the Doxygen build stays at 0 warnings

Version 2.1.1 (26/07/2026)
********************
Feature: Added NewProcessEx / ReadProcessOutput / SendProcessBreak in Utils for the Psyclone T1.4 external-exec lifecycle (cross-platform child-process spawn, output capture and graceful-break signalling)
Feature: TriggerGroup declarative-join support — CMSDK primitive backing the Psyclone <triggergroup> grouped-activation feature, with grouped-delivery documented in the CMSDK LLM guide and Doxygen-clean header comments
Fix: Fixed an intermittent network_http teardown hang — a double-delete race in NetworkChannel endConnection/shutdown; teardown now uses bounded waits plus invalid-handle hardening (verified 20/20 clean test=cmsdk runs)
Fix: Fixed Windows GetExitCodeProcess misuse — a still-running process was reported as terminated with code 259 (STILL_ACTIVE); process-exit detection is now correct
Fix: Fixed a Linux SIGSEGV/hang introduced by the graceful-shutdown thread change — thread reaping is now safe on Linux
Fix: Fixed intermittent Windows unit-test failures — graceful thread shutdown plus WAIT_ABANDONED handling
Fix: Windows shared memory now honours force by zeroing a pre-existing named mapping; assorted minor Windows compilation fixes
Fix: SSL — OpenSSL handshake/certificate errors are now routed through the log system; client-side hostname verification and custom CA locations; verify-peer default with allowselfsigned opt-in
Fix: Corrected Subscriptions.h trigger-filter doc-comments — maxage operand is milliseconds (not microseconds), haskey matches any entry type, >=/<= epsilon boundary noted on greaterthan/lessthan, numeric ops parse as float64
Build: Clean builds from scratch fixed — the build/ object directory is now self-created by the compile rules (mkdir -p $(@D)) rather than a parse-time guard, so make clean && make and make rebuild work out of the box

Version 2.1.0 (12/07/2026)
********************
Feature: Native macOS support — CMSDK now builds and runs correctly on Apple Silicon/Intel macOS as a first-class platform alongside Linux and Windows, with a full passing unit test suite
Feature: Added a unified CMSDK unit test framework (UnitTestFramework.h/.cpp) — one PASS/FAIL line per object, indented perf metrics, timestamped performance JSON (cmsdk_perf_latest.json) with compare=<file> %-deltas for an automated regression-tracking loop, a live overwriting progress line, per-test process isolation with a timeout (a crash/hang in one test can't take down the suite), and self-healing shared-memory cleanup so a killed run can't poison the next
Feature: Authored/converted ~20+ object unit tests: Base64, hash (MD5/SHA1/SHA256/CRC32/SHA3/Keccak), MathClasses, Bitmap, HTML, xml_parser, Subscriptions, VantagePoints, Observations, ControlMessage, ThreadManager, DataMessage, NetworkManager, RequestGateway, ComponentMemory, ProcessMemory — 33 tests total, all passing
Feature: Added a `network_https` unit test — a real TLS handshake plus encrypted HTTP round-trips over loopback with a runtime-generated self-signed certificate — for SSL/TLS builds
Feature: Added `-O0` unoptimised debug/ssldebug build targets for a real single-step debugging experience (previously debug builds were still optimised, making breakpoints unreliable)
Feature: Added a per-test hang-diagnostic mechanism — on timeout, the child is signalled (SIGUSR1) to dump a native stack trace of exactly where it hung before being killed, and the parent reports the last progress phase recorded, instead of a bare "timed out"
Fix: Fixed a macOS-only thread-liveness bug that caused shutdown hangs across the whole product — IsThreadRunning/CheckForThreadFinished used a destructive pthread_join as a liveness probe (which reaps the thread), so a later authoritative join operated on an already-joined pthread_t: heap-corrupting undefined behaviour. Switched to non-destructive pthread_kill(h,0) liveness probing plus a single authoritative join, with null-handle guards
Fix: Fixed two macOS-only timeout-emulation primitives (macos_pthread_mutex_timedlock, macos_pthread_join_with_timeout) that treated an absolute deadline as a relative countdown / used an already-expired deadline, so bounded waits silently became indefinite hangs under contention — root cause of intermittent 30s teardown hangs and 6-27s stalls on IsThreadRunning
Fix: Fixed macOS CPU percentage calculation — GetProcAndOSCPUUsage mixed Mach clock ticks (~100/sec) with microsecond-scale process ticks, inflating reported CPU usage by roughly 10,000x
Fix: Implemented real per-thread CPU measurement on macOS via pthread_mach_thread_np + Mach thread_info (previously a stub returning false / garbage stats for Root-space components such as AudioInput/AudioOutput)
Fix: Fixed ComponentMemory/ProcessMemory off-by-one arena bounds checks (were using > instead of >= indexSize) and resize/destroyComponent memmove lengths that were over-copying by indexSize*8 bytes
Fix: Fixed OpenSharedMemorySegment(size=0) reading its size from an offset the caller's own header immediately overwrites; now autodetects the real size via fstat
Fix: Fixed a NetworkChannel::shutdown() deadlock — it held channelMutex while joining a worker thread that also needed the same mutex — plus an unsigned-integer underflow in a wait timeout calculation
Fix: Fixed NetworkChannel::waitForMessage never setting its connection-id out-parameter, so a receiver had no way to reply to the correct sender; now tracks the source connection id per message
Fix: Fixed a NULL-pointer crash in RequestGateway::addToCallLog constructing std::string from NULL getString() results (e.g. a DataMessage request with no "User-Agent"); parameters are now NULL-safe
Fix: Fixed Stats::getMedian off-by-two iterator bug and a mutex leak on an early return
Fix: Fixed Point::getDistanceTo using the X coordinate twice instead of X and Y
Fix: Fixed corrupted multibyte character literals in HTML2Char that broke the build on some toolchains
Fix: Fixed aarch64 Linux builds incorrectly detected as 32-bit (BITARCH/-fPIC), breaking builds on ARM64 Linux (e.g. Raspberry Pi 5)
Fix: Fixed Linux Python3 build — hardcoded python3.4m include/lib paths replaced with sysconfig-derived paths matching the macOS branch; fixed an LP64 SWIG binding word-size mismatch (vector<long> vs vector<long long> ODR clash) that broke the wrapper build on 64-bit Linux
Fix: Fixed the make bsd distribution build failing on macOS — replace.sh used the GNU-only sed -b flag, which BSD sed rejects; the flag is now feature-detected at runtime, and sed runs under LC_ALL=C so non-UTF-8 template files cannot trigger BSD sed's "illegal byte sequence" error (byte-transparent, preserves CRLF; GNU sed behaviour on Linux/Cygwin unchanged). Verified identical distribution archives on macOS and Linux
Perf: TCP messaging throughput ~42k → ~90k msg/s and latency 23.8us → ~11us (~2x improvement) by keeping sockets non-blocking instead of flipping blocking mode around every send (previously 4 fcntl syscalls/message plus a race with the receive thread on the same socket)
Perf: UDP messaging throughput ~107k → ~155k msg/s and latency 9.3us → ~6us via the same socket-mode and buffered-read optimisations
Perf: Removed a redundant per-read SetSocketNonBlockingMode call (2 fewer fcntl syscalls per read)
Perf: NetworkConnection::receive() now only reads from the socket when the buffer doesn't already hold the requested bytes — a single drain typically pulls a whole message (or several pipelined messages), so most subsequent reads cost no syscall at all
Perf: MessageProtocol::ReceiveMessage now peeks the header into a stack buffer and does a single malloc(size), replacing a malloc(1KB)+free+malloc(size) sequence on every message
Perf: Replaced a per-message 36KB recent-message ring memmove in both ComponentMemory and ProcessMemory with a circular write index (recentInPos/recentOutPos), removing a large memmove from the hot messaging path
Perf: PsySpace*Run thread functions return THREAD_RET without a heap allocation
Perf: CMSDK DataMessage construction/serialisation and general networking hot paths optimised (unittest + optimisation pass)
Perf: RequestGateway/NetworkManager test harnesses warmed up and stabilised so back-to-back and concurrent runs no longer fail on transient address-in-use or teardown-timing races — validated with a 1500-run soak, zero failures, no hangs

Version 2.0.0 Beta 3 (02/07/2014)
********************
Fix: Fixed HTTP server connection issues
Fix: Fixed more memory leaks
Fix: Fixed several network protocol and connection problems
Fix: Since this is still in Beta there are more fixes than can be listed here
Performance: Improved messaging performance
Feature: Added statistics functions and objects (MovingAverage, etc.)
Feature: Added DataMessage toXML and toJSON

Version 2.0.0 Beta 2 (23/05/2014)
********************
Fix: Fixed memory leaks
Fix: Since this is still in Beta there are more fixes than can be listed here
Performance: Improved messaging performance

Version 2.0.0 Beta 1 (09/05/2014)
********************
Complete rewrite of all CoreLibrary source code, design and implementation
