# Changelog

All notable changes to Agent Recon will be documented in this file.

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

## [Unreleased]

## [1.2.1] - 2026-08-27

A security-hardening release. Every item from the security backlog carried forward from the v1.2.0 review is closed, along with several issues found during the work that were not on that list. There are no new features.

**Upgrade note.** Two behaviour changes are worth knowing before you update:

- The dashboard must now be opened at `localhost` or by IP address. Reaching it by machine name (NetBIOS, `.local`, or a hosts-file alias) returns 403. This is what closes the DNS-rebinding hole described below; addresses the server actually binds — including a WSL or Hyper-V gateway IP — continue to work.
- Your licence key and OpenTelemetry custom headers are now encrypted at rest, migrated automatically on first start. This is one-way: downgrading below 1.2.1 after upgrading would leave those two settings unreadable.

### Security

- **Closed a DNS-rebinding hole affecting most of the dashboard.** A web page you visited could point its own domain name at your machine and reach the local API — reading your event history, deleting it, or changing allowlist rules — because the connection genuinely terminates on an address the server owns, so neither the IP allowlist nor the network-bind boundary can tell it apart from the real dashboard. The `Host` header is now checked against the loopback names plus the addresses the server actually bound. Event ingestion is deliberately exempt so hook forwarding can never fail silently.
- **Two secrets were stored unencrypted on disk.** Your licence key and the OpenTelemetry custom headers (which routinely carry a bearer token) are now encrypted at rest. They remain readable through the settings screen, so copying your licence key and editing your collector headers work exactly as before.
- **Fixed a denial-of-service in personal-information scanning.** A crafted event could make the email-detection pattern backtrack catastrophically and freeze event ingestion for tens of seconds — indefinitely at the maximum request size. The pattern is now bounded, and both detection and redaction run under a hard work budget.
- **Personal information beyond the scan limit is now detected.** Long prompts and file edits were only scanned up to a cap, so anything past it was never detected and therefore never redacted. Input fields are now scanned in full, in overlapping windows, within that budget.
- **Security evidence no longer stores secret values.** Matched text shown in the security view had been persisting real credential bytes; credential-shaped content is now masked while the evidence stays readable for triage.
- **Closed a cross-site-scripting class in the dashboard.** Seventeen places interpolated data directly into inline click handlers, where HTML escaping does not protect a JavaScript string context. All of them now use event listeners and data attributes, and a test blocks reintroduction.
- **Two endpoints were reachable too easily.** The provider-connection test (which reveals whether an API key is configured and spends it on an outbound call) was ungated entirely, and hook installation (which writes to your home directory) checked only the `Host` header. Both now require a genuine same-machine caller.
- **Outbound endpoint settings can no longer be pointed at cloud metadata services.** Validating the URL when it is saved cannot prevent this, because a hostname can resolve differently later; the address is now checked at connection time. Local and private-network collectors are unaffected and still supported.
- **Azure telemetry no longer trusts a spoofable client-IP header.** Rate limiting and install attribution used the leftmost `X-Forwarded-For` value, which a caller supplies — making both limiters bypassable by rotating it, and growing their tracking maps without bound.
- **Hardened the release pipeline.** A crafted release tag could inject shell commands into the packaging workflow; the privileged release action floated on a mutable tag and is now pinned to an exact commit; and the installer's service-control commands no longer build shell strings from file paths.
- **The archive encryption key can no longer be written to disk in the clear.** A fallback path minted a fresh key and saved it unencrypted, bypassing the startup check that refuses to run without a real keystore. Migration from the legacy key file now also removes that file, but only after confirming the key reads back correctly.
- **Fixed a command-injection path in Windows credential storage.** The stored credential blob was interpolated into a PowerShell script; it is now passed as data and validated.
- **Corrected a stale native-library pin.** Linux — the primary server platform — was loading a three-minor-old build of the security scanner because one manifest disagreed with the others. A test now enforces that they match.

### Fixed

- **The dashboard works over IPv6 loopback.** Opening it at `[::1]` returned 403 because the address was parsed as though it were a `host:port` pair.
- **Forged model names no longer produce a broken cost figure.** A model name matching a built-in JavaScript property yielded `NaN` instead of falling back to default pricing.
- **Automatic allowlist learning no longer considers data-exfiltration patterns.** Repeated activity in that category could previously be promoted to an allowlist rule.

### Changed

- **Installs now work under npm 12.** npm 12 stopped running dependency install scripts by default, which prevented the native database library from building — leaving a fresh install unable to start, with a misleading "rebuilt successfully" message. The required trust grant now ships with the package.
- **Dependencies updated**, clearing eleven advisories, including the embedded database library (major version), the installer's prompt library (major version), and the build toolchain. `npm audit` reports no known vulnerabilities.
- **Dependency monitoring widened** to every manifest in the repository plus GitHub Actions, which previously went unwatched — the reason the mutable release-action tag went unnoticed. Update notifications are also labelled honestly now, so a security label means a security fix.


## [1.2.0] - 2026-07-09

### Added

- **Multi-tool support — Cursor & GitHub Copilot CLI**: Agent Recon now observes sessions from Cursor and GitHub Copilot CLI alongside Claude Code. Per-agent hook forwarders tag each event with its source agent and hand off to a detached background worker, so even a blocking pre-tool hook returns to the host agent in milliseconds. Server-side agent mappers (`server/agents/cursor.js`, `server/agents/copilot-cli.js`) rewrite each agent's event and tool names into the canonical vocabulary, so security classification, PII scanning, and auto-baseline work identically for every agent. The installer detects Cursor (`~/.cursor/`) and Copilot CLI (`~/.copilot/`) and registers their hooks; the dashboard shows a clickable source-agent badge that filters the feed.
- **Multi-mode billing-aware cost tracking**: token cost is now honest per billing mode. Real per-token dollars are shown only for direct Anthropic API keys; Bedrock/Vertex show an approximate (region-dependent list price); Claude Pro/Max/Team subscriptions show tokens only (the flat subscription fee makes a per-token dollar figure fictional). The billing mode is detected per session from the hook auth signal, falling back to an account-level setting. Cost-savings advice denominated in dollars is suppressed in the non-API modes. (Database schema v6.)
- **Context observability for live sessions**: a new bar under each session swimlane infers what Claude is currently operating from — the facts, constraints, source files, and assumptions — by reading the event stream with a Haiku-class model, with per-item provenance (new / changed / stable) computed deterministically. A companion context-window fill gauge shows how full each session's context window is, fed from the statusline. (Licensed tier; database schema v5.)
- **Sub-agent observability graph**: spawned sub-agents are now tracked as first-class rows — parent/session linkage, prompt, result, timing, and token counts — surfacing the delegation graph for a session. (Database schema v7.)
- **Plain-English event cards**: the Sessions feed now renders each event as a human-readable summary with per-session model and harness badges, and a unified "Details" disclosure for the raw payload — readable by non-technical users, with full detail one click away.
- **Homebrew and Scoop packaging**: Agent Recon can now be installed via `brew install` (macOS/Linux) and `scoop install` (Windows), each of which pulls in Node.js automatically. Published from the release workflow alongside the npm package.

### Changed

- **Current-model pricing, single-sourced**: the pricing table now seeds current Claude models (including Opus 4.8 and Fable 5) and prices `claude-sonnet-5` explicitly rather than falling back to a generic Sonnet rate. The frontend reads pricing from a single server endpoint instead of a hard-coded table.
- **npm publish via OIDC Trusted Publishing**: releases now publish to npm using short-lived OIDC credentials configured per-package on npmjs.com, and the long-lived `NPM_TOKEN` secret has been removed (part of the industry-wide response to the May 2026 npm token compromise).
- **Tool-neutral hook install directory**: forwarder scripts now install to `~/.agent-recon/hooks/` (previously `~/.claude/hooks/`, which confused non-Claude users); pre-existing installs are migrated automatically.
- **Event normalization runs before dedup**: the `/event` ingest path now normalizes an event via its agent mapper before the dedup fingerprint and synthetic-session guard, so non-Claude agents (whose raw payloads use different field names) dedup correctly.
- **Installation manifest schema v3**: adds an `agents` block recording per-agent (Cursor / Copilot CLI) hook installs. v2 manifests are still read without error.
- **Removed the header environment-status chip** in favor of the richer Environment tab.

### Fixed

- **Retention could delete un-archived data**: the archiver is now the single deletion authority and always archives (encrypted) before deleting, with a minimum-retention floor and an audit log, closing a race that could remove events before they were archived.
- **PII could persist past the scan window**: machine-output fields (tool results, agent prompts/results) longer than the scan cap are now truncated at rest, and the redactor now removes every PII type the detectors flag (bare SSN/PAN, passport, driver's license, US-format date of birth, personal name, short IBAN) instead of a narrower subset (CWE-212). Multi-tool mapper fields outside the redaction allowlist are also scrubbed at store time.
- **GitHub Copilot CLI hooks on Windows**: the installer now emits the schema's dedicated PowerShell hook field, quotes the node and script paths, and the forwarder strips a UTF-8 byte-order mark from hook stdin — three fixes that together let Copilot CLI (and Cursor) deliver events reliably on Windows.
- **Newer Anthropic models rejecting sampling params**: the LLM client drops the `temperature` parameter and retries when a model returns a 400 for an unsupported sampling parameter.
- **Nav quota widget** now stays on screen (marked stale) when Claude Code goes idle instead of disappearing, and the statusline pipeline preserves each sub-object on merge.
- **Update-check failures are now persisted** and surfaced, and the admin dashboard gained per-install search and correct UTC timestamps.

### Security

- **Comprehensive security remediation (36 findings, AR-SEC-001..036)**: strict network bind selection so the server never binds the physical NIC (a physically separate machine gets connection-refused); credential storage now fails closed and refuses to start on an insecure posture unless explicitly opted out; a WebSocket Origin allowlist (anti-CSWSH); a fail-closed `files[]` publish allowlist protecting against accidental file leakage in the npm tarball; and settings master-key rotation.
- **Admin telemetry endpoints hardened**: all `mgmt-*` reader endpoints and `compliance-review` now require AAD authentication (they were world-readable and had been exposing customer data); the admin dashboard reaches them via a silently-acquired AAD bearer token. The email MCP endpoints likewise moved from a static function key to AAD bearer auth.
- **Pre-release fixes**: `GET /api/settings` is loopback-gated to stop cleartext secret disclosure; a stored XSS in the admin dashboard via a client-controlled `X-Forwarded-For` header is closed by validating the source IP; and approval-gated `PermissionRequest` events are now security-classified identically to `PreToolUse` (so a `curl | sh` sitting at an approval prompt is classified, not rendered as a benign notification).

## [1.1.0] - 2026-05-02

### Added

- **Auto-learning security baselines**: the Security tab now observes recurring tool/category/path patterns and surfaces them as candidate allowlist rules in a review panel. Anti-poisoning gates exclude secret/injection/privilege-escalation categories and PII-bearing events; require diversity across sessions, agents, and projects before a candidate appears; and never auto-promote — the user accepts or rejects each one. Reduces manual allowlist curation for typical workflows. (F1)
- **Per-event tool execution duration**: Claude Code v2.1.119+ PostToolUse hooks now carry a `tool_duration_ms` field that is captured per event and surfaced in the dashboard, enabling latency analysis at the individual tool-call level. (F12.10, schema v3)
- **Statusline rate-limit widget**: a new header indicator and Environment-tab panel show Claude Pro/Max usage windows (5h, 7d) live, fed by a statusline hook wrapper that POSTs the user's `rate_limits` payload to a dedicated endpoint. Coalesced WebSocket broadcasts and a 5-minute absence timer keep the widget accurate without amplification. (F11.3)
- **Statusline session-state capture**: `effort.level` (forward-compatible charset) and `thinking.enabled` (strict boolean) now flow through the statusline pipeline alongside rate limits, with HTML-escape and 4 KB body cap for defense-in-depth. (F13.1, F13.2)
- **OTEL trace correlation**: every event ingested from a Claude Code hook now opportunistically captures the W3C `traceparent` and `tracestate` headers if present, persisting `otel_trace_id` and `otel_span_id` per event for downstream correlation with OTEL backends. (F12.7, schema v2)
- **Claude Code v2.1.108+ event coverage**: Elicitation/ElicitationResult security classification, PushNotification built-in tool, large-result tagging on PostToolUse with oversized `_meta`, and other event-model deltas. (F12.1–F12.5)
- **`agent-recon start` / `stop` / `status` CLI commands**: the installer CLI now exposes runtime commands that dispatch to the platform service manager (systemd/launchd/NSSM) when present and otherwise spawn `node server/start.js` directly. `stop` uses graceful HTTP shutdown via `POST /api/shutdown` with WAL checkpoint and buffer flush — critical on Windows where SIGTERM is `TerminateProcess()`. Foreground default + `--detach` flag + state file. (BUG-4 / F7)
- **YARA-X cross-platform binary auto-heal**: `start.js` detects the platform-specific NAPI-RS prebuilt and auto-fetches the missing one on first start (gated on TTY, npm on PATH, and `node_modules` write permission). Fixes the silent security-tier degradation on cross-platform installs (e.g., `npm install` on WSL skipping the Windows binary). (Issue #89)
- **In-app docs modal updated**: Reflects F11.3 statusline pipeline, F12 event-model coverage, and `mcp_tool` settings.json shape introduced in Claude Code v2.1.118. (F13.3)
- **`mcp_tool` hook documentation**: settings.json shape and routing semantics now documented in the architecture reference.

### Changed

- **Schema migrations harden against `user_version` drift**: every migration now checks for the actual presence of columns/tables via `PRAGMA table_info` rather than trusting `user_version` alone, and ALTERs are idempotent. Protects against the rare-but-real case where `user_version` advances without DDL committing (interrupted migration, pragma surviving rollback). v1→v2, v2→v3, and v3→v4 all gated this way.
- **Database schema bumped to version 4**: adds `events.otel_trace_id` and `events.otel_span_id` (v2), `events.tool_duration_ms` (v3), and the `auto_baseline_patterns` table plus a `source` column on `allowlist_rules` (v4, default `'manual'`). All migrations apply automatically on first start of v1.1.0.
- **Allowlist rule sources**: rules now carry a `source` field (`manual`, `profile`, `auto-learned`) with priority ordering — auto-learned rules ship at priority 200, profile-seeded at 100, manual at 50 (lower wins).

### Fixed

- **Installer cleanup**: `cli.js` path resolution corrected, mkcert presence is pre-validated before TLS preselection, and WSL TLS gates align with the post-fix mkcert contract. Closes installer issues #85, #86, #87, #92. (PR #93)
- **`agent-recon stop` survives TLS redirect**: the stop command now tries HTTPS first, falling back to HTTP, so a server bound to TLS no longer 301s a `POST /api/shutdown` into a hung state. (Issue #88)
- **Statusline wrapper survives TLS redirect** and falls back to the WSL gateway IP when localhost forwarding drops TLS ports.
- **Installer writes camelCase `statusLine` block** per Claude Code's actual settings.json contract (lowercase variants are silently ignored).
- **WSL `install --force` verify step no longer spawns a local server** that conflicts with the running Windows server. (Issue #84)
- **Integration test no longer hits the live Azure telemetry endpoint** during `npm run test:int` runs in CI. (Issue #83)
- **WorktreeCreate/WorktreeRemove hooks removed from registration**: Claude Code treats these as action hooks (custom VCS worktree creators), and Agent Recon's telemetry-only hooks were breaking worktree isolation. Surgical strip-on-upgrade preserves third-party hooks. (BUG-1)
- **Update-check error surfacing**: Settings panel and Environment view now display network errors (timeout, HTTP 301, etc.) instead of silently reverting to last-good state. (BUG-3)
- **`site/version.json` auto-update on release**: the release pipeline now updates `site/version.json` and syncs it to the Pages repo, eliminating stale `latest:` values that broke update notifications. (BUG-2 / CF-10)
- **Decision-tail cleanup + Fix Now banner button** on the Security tab.
- **Latent timer leak in rate-limit widget**: `_rlCountdownTimer` setInterval now `.unref()`s, preventing test isolation processes from staying alive between runs.

### Security

- **`server/server.js` auto-heals YARA-X platform binary on first start**, eliminating a silent security degradation when users `npm install` from a different platform than the one they run on. The YARA scanner falls back to a no-op only if the heal fails after a real attempt — never silently.
- **`/api/statusline` endpoint hardening**: requires localhost `Host` header (defeats DNS-rebind from browser tabs), 4 KB body cap, payload-shape validation, coalesced broadcasts (defends against amplification at high tick rates with multiple dashboard tabs).
- **Auto-learning baseline anti-poisoning**: hard-exclude on `secret`, `inject`, `priv-escalation`, `prompt-secret`, `prompt-injection` categories; skip events with `pii_types`; per-session occurrence cap; ≥2 distinct agents and ≥2 distinct projects required before promotion. The user (not the system) accepts or rejects every candidate.
- **Dependency hygiene**: `terser` 5.46.1 → 5.46.2 (dev), transitive `fast-xml-parser` and `hono` updated.

## [1.0.7] - 2026-04-12

### Fixed

- Installer: removed WorktreeCreate/WorktreeRemove hook registrations — Claude Code treats these as action hooks (custom VCS worktree creators), not observation hooks, causing worktree isolation to fail for all Agent Recon users
- Installer: added EVENTS_DEPRECATED mechanism that surgically strips stale WorktreeCreate/WorktreeRemove hooks from existing settings during upgrade (preserves third-party hooks)
- Setup scripts: all 4 platform scripts (Windows, WSL, Linux, macOS) updated with same fix and upgrade-path stripping

### Added

- Installer: 3 regression tests for the deprecated-event stripping mechanism

## [1.0.6] - 2026-04-08

### Fixed

- Installer: upgrade instructions now say `agent-recon upgrade` instead of `node cli.js upgrade` for global npm installs (B11)
- Service: display names reference "Agent Recon" generically instead of "Claude Code" (supports multi-agent future)
- CI: Docker Fedora test updated from Fedora 39 (Node 20) to Fedora 41 (Node 22+)

### Added

- Site: macOS and Linux prerequisites added to install documentation
- Site: Windows prerequisites callout added to install section

## [1.0.5] - 2026-04-07

### Fixed

- Windows: process monitor spawned visible PowerShell console window every 2 seconds, creating an infinite loop of flashing windows that persisted after installer exit (B10)
- Windows: added `windowsHide: true` to all child_process calls that spawn PowerShell or background processes (credential store DPAPI, installer env detection, service management, server spawn)

### Added

- Codebase-wide audit test (`windows-hide-audit.test.js`) — prevents future regressions by scanning all source files for bare exec/spawn calls missing `windowsHide: true`

## [1.0.4] - 2026-04-07

### Fixed

- Windows: hook commands now use forward slashes — Git Bash no longer mangles backslash paths (B7)
- Installer: directory validation accepts `start.js` (npm esbuild bundle) in addition to `server.js` (B8)
- Global install: `platform.dataDir()` resolves to user-writable path, eliminating EACCES on Linux/macOS
- CLI: `--version`/`--help` no longer emit spurious non-TTY warning over SSH

### Added

- Windows smoke test (`test/platforms/smoke-test-windows.ps1`) — 9-check PowerShell equivalent of `smoke-test.sh` (B9)

## [1.0.3] - 2026-04-06

### Added

- Installer: `--yes` / `-y` / `--non-interactive` flag for unattended CI and remote installs (accepts all defaults without prompts)
- Installer: auto-detects non-TTY stdin and enables non-interactive mode automatically

### Fixed

- INSTALL.md: build tools moved from prerequisites to troubleshooting (only needed when prebuilts unavailable)
- INSTALL.md: added Ubuntu/Debian warning about `apt install nodejs` shipping old versions (Node 12/18 vs required 22+)
- INSTALL.md: lifecycle event count corrected from 13 to 25
- INSTALL.md: added `--yes`/`--non-interactive` flag documentation to CLI commands

## [1.0.2] - 2026-04-06

### Fixed

- npm package shipped unbundled start.js causing MODULE_NOT_FOUND crash on launch
- Release pipeline: bundle swap now uses npm prepack/postpack lifecycle hooks to prevent timing race
- CI publish step now uses pre-built tarball instead of re-packing from source
- Tarball validation checks that bundled start.js is present before release
- Setup scripts (Linux, macOS, WSL, Windows) now register all 25 Claude Code hook events (was 13, missing v2.1.x events)
- PowerShell setup script now correctly adds `matcher` property for wildcard hook events
- Credential store: server crashed on Linux without `secret-tool` (PBKDF2 fallback required env var to store auto-generated master key)
- Credential store: all file-writing backends now set 0o600 file / 0o700 directory permissions
- Credential files renamed from `.dpapi` to `.cred` (misleading extension on non-Windows platforms)
- `getMasterKey()` error message referenced non-existent `--init-keys` flag

## [1.0.1] - 2026-04-03

### Changed

- Server code bundled into single minified file for IP protection (esbuild)
- npm tarball reduced from 84 to 44 files
- Dynamic LLM provider loading replaced with static mapping for bundle compatibility

### Fixed

- npm publish step added to release workflow (was missing, caused E404 for users)
- .npmignore gaps: excluded internal test procedures, hardware analysis, build tools, CLA

## [1.0.0] - 2026-04-03

### Added

- Real-time event feed with WebSocket streaming from Claude Code hook scripts
- Multi-environment support (Windows, macOS, Linux, WSL, VS Code, tmux)
- Scrolling waveform timeline canvas with per-session swimlanes
- Security classification engine (browser-side regex + server-side YARA-X rules)
- LLM-powered security chain analysis with context-aware risk calibration
- Token cost tracking with Usage API polling and per-session breakdowns
- Per-session AI-generated insights and prompt quality coaching
- Hallucination risk scoring (two-tier: direct evidence + circumstantial signals)
- Environment recommendations based on 7-day rolling analysis
- Session history narratives with LLM-generated title and detail summaries
- Session labels with project-aware naming (<project>:<hex> format)
- Multi-provider LLM abstraction (Anthropic fully implemented; OpenAI, Google stubs)
- Per-pipeline provider and model configuration via settings
- Cross-platform installer CLI (detect, install, upgrade, uninstall)
- OS-native credential storage (DPAPI, Keychain, libsecret, PBKDF2 fallback)
- AES-256-GCM encrypted settings for API keys at rest
- AES-256 encrypted session archives
- PII detection and automatic redaction before storage
- Privacy-respecting telemetry with opt-out and self-service data deletion
- OpenTelemetry export (OTLP/HTTP for logs, traces, metrics)
- Browser-trusted TLS via mkcert (HTTP / mkcert / custom certificate modes)
- Three-tier licensing (Community, Personal, Professional) via Lemonsqueezy
- Feature gating with upgrade overlays for LLM-powered features
- Landing page (agent-recon.net) and storefront integration
- Azure telemetry backend with admin dashboard and compliance review workflow
- In-app documentation modal with tabbed sections
- Comprehensive developer documentation (API reference, architecture, database schema)
- Cross-platform CI (Ubuntu, Windows, macOS Intel/ARM, Docker matrix)
- Platform-aware setup scripts and service templates (launchd, systemd, NSSM)
- Homebrew and Scoop package manager templates

### Security

- Server-side PII scanning with confidence-scored regex detection and redaction
- YARA-X rule-based security classification of tool calls and events
- Gitleaks-compatible secret detection configuration
- IP allowlist restricting server connections to private network ranges (127.x, 10.x, 172.16-31.x, 192.168.x)
- HMAC-SHA256 webhook signature verification for Lemonsqueezy events
- Azure deployment with managed identity, Key Vault, VNet, and firewall hardening

[1.1.0]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.1.0
[1.0.7]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.0.7
[1.0.6]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.0.6
[1.0.5]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.0.5
[1.0.4]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.0.4
[1.0.3]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.0.3
[1.0.2]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.0.2
[1.0.1]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.0.1
[1.0.0]: https://github.com/genxcoder1999/agent-recon/releases/tag/v1.0.0
