# Changelog

All notable changes to the Syntropy Elixir package. Versions follow
[SemVer](https://semver.org/); entries accumulate under Unreleased until a
publish, then move under the released version.

## [0.3.0] — Unreleased

The runtime goes headless and gains its receipts backbone: the package now
ships the engine and its API surface only, and the engine can verify a
change by running the target repository's own checks.

### Added
- `code_review` run kind: `POST /api/runs` with `kind: "code_review"` and a
  `code_review` object (`repo_path`, `base`, optional `head` and `checks`)
  executes the repository's checks against the diff and completes with
  `rc-*` **receipts** in the run envelope — tool, argv, tool version, exit
  code, duration, a SHA-256 digest of the full output, and a bounded output
  tail, each bound to the review's `diff_sha`. Gated behind
  `SYNTROPY_ENABLE_LOCAL_REPO_REVIEW` outside dev, exactly like the local
  source tool.
- Check detection from project manifests (Elixir, Python, Node, Rust, Go;
  `semgrep`/`osv-scanner` when configured) with a `.syntropy/review.toml`
  override that replaces detection. Missing tools produce `skipped`
  receipts instead of silently narrowing coverage.
- Supervised check execution: ports in the target repo's working directory
  with a scrubbed environment (no `MIX_ENV`/`ERL_*`/`RELEASE_*` leakage),
  per-check timeouts that kill the OS process, and run cancellation that
  kills mid-suite through a tombstone-protocol tracker.
- `receipt_recorded` runtime event per executed check; `receipts` and
  `code_review` fields on run envelopes and the runs API.

### Removed
- The operator Mission Control (LiveView console), UI components, operator
  session auth, and all web assets. Operator UI ships with the Syntropy app
  going forward; the engine is driven through the JSON API, websocket
  channels, and the Python SDK/CLI.
- UI-only dependencies: `phoenix_live_view`, `phoenix_live_reload`,
  `phoenix_html`, `lazy_html`.

### Changed
- `SyntropyWeb.Endpoint` no longer serves static assets, the LiveView
  socket, or cookie sessions; the `/socket` websocket API channel and all
  `/api` routes are unchanged.
- Connection shaping for agents/history JSON moved to
  `SyntropyWeb.Api.AgentConnections` (public API output is unchanged).

## [0.2.0] — 2026-07-07

Coordinated release with `syntropy-core` 0.2.0 (PyPI); the shared
runtime-events contract is at 0.2.0.

### Added
- Control-plane REST endpoints: `POST /api/agents` and
  `DELETE /api/agents/:id` (with `LatticeSupervisor.remove_agent/1` and
  knowledge cleanup), `POST /api/recommendations/:id/approve` and `/reject`,
  and best-effort `POST /api/runs/:id/cancel`.
- Runtime provider configuration API (`/api/runtime-config`) with candidate
  validation and provider connectivity testing.
- Shared specialist perspectives catalog served at `GET /api/perspectives`.
- Webhook delivery: in-memory registry, supervised dispatcher delivering
  HMAC-SHA256-signed POSTs with bounded retries, per-endpoint delivery logs,
  and `/api/webhooks` management endpoints.
- `thought_preview` payload key on `agent_thought` events (shared
  runtime-events contract 0.2.0, mirrored in the Python runtime).
- Unique `uid` on every runtime event, persisted with a unique index and
  exposed in event JSON alongside the existing `id` event name.
- Cluster-federated event history: recorders merge remote-node events with
  uid deduplication, so `GET /api/events` and the cockpit event panel show
  cluster-wide history.
- Cross-node run cancellation: `cancel_run/1` falls back to RPC on the
  coordinating node, so any node can cancel any run in the cluster.
- Prometheus metrics at `GET /metrics` (open in dev/test, bearer-token-gated
  in prod) covering BEAM, Phoenix, and Ecto plus custom task run, LLM
  request/token, webhook delivery, and event recorder flush metrics.
- Production packaging: `mix release` configuration, multi-stage Dockerfile,
  `railway.toml` with `/api/ready` health checks, and boot-time cluster
  bootstrap validation for static clustering.
- IPv6-only private network support for hosted deployments (Railway, Fly.io):
  `SYNTROPY_CLUSTER_INET6=true` switches Erlang distribution to `inet6_tcp`,
  and `ECTO_IPV6=true` opens inet6 database sockets. The release env script
  also starts epmd explicitly before boot, since the BEAM's implicit epmd
  autostart is unreliable in minimal containers.

### Changed
- License clarified: still Business Source License 1.1 (Fair Source), now with
  an Additional Use Grant permitting production use for organizations under
  US $1M in revenue/funding and forbidding hosted or managed Syntropy services
  at any size. Each version converts to Apache 2.0 four years after release.
  The LICENSE file now ships inside the package, the Hex description says
  "fair source" instead of "open-source", and the package links point at the
  `syntropy-os/syntropy` repository.
- Mission control LiveView layout and dashboard styling refinements.
- `EventRecorder.record/2` is now asynchronous: events broadcast immediately
  and persist in batched inserts; a synchronous `flush/0` helper exists for
  tests and shutdown paths.
- `task_scheduler.ex` decomposed into focused submodules (source inquiry,
  run envelopes, selection, synthesis, agent dispatch) with no behavior
  change.

### Fixed
- `ClusterMonitor` now reconciles on a periodic tick (15s default) in
  addition to node events, so a node that booted before its peers no longer
  reports a stale `forming` cluster status after the peers connect.
