Skip to main content

Changelog

This page tracks documentation-noteworthy changes — new endpoints, schema breaking changes, deployment surface shifts, security posture. Detailed commit-by-commit history lives in the GitHub log.

2026-05-08

Security and reliability hardening sweep. 23 PRs across server / web / desktop / CLI / MCP, surface-by-surface.

Security defaults

  • DEBUG defaults to False, ALLOWED_HOSTS defaults to 127.0.0.1,localhost. apps/server/entrypoint.sh refuses to boot when CLONE_ENV=production AND DEBUG=True. (#87)
  • /api/voice/{tts,stt,clone}/ now require authentication (@permission_classes([IsAuthenticated])). Transcript text and voice ids no longer printed to stdout. (#86)
  • DRF throttling: login (10/min anon), /predict/ + /predict/batch/ (60/min user), /voice/* (30/min user). (#106)
  • nginx serves HSTS, CSP (script-src 'self', frame-ancestors 'none'), X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin; per-location client_max_body_size caps for /api/recording/ (8m) and /api/voice/ (16m). (#105)

Calibration & decay

  • batch_predict_view now applies per-user Platt scaling, mirroring predict_view. Both endpoints return calibrated confidence plus raw_confidence (raw stays in Prediction.confidence for the daily fitter). (#95)
  • fit_for_user caps to the 5000 most recent labeled rows + accepts a since cutoff; fit_platt honors per-sample weights. (#99)
  • Behavioral decay is now atomic (select_for_update inside transaction.atomic) and flip-aware — flipping accepted → rejected reverses the prior +0.04 and applies -0.08, instead of the old "second flip is a noop" semantic. (#98)

Auth

  • ApiKeyAuthentication falls through to JWT when a stale X-Clone-API-Key is presented alongside a valid Authorization: Bearer …. Bad-key-only requests still 401 with the explicit message. (#97)
  • Web: AuthContext.fetchWithAuth injects the access token, refreshes once on 401 via /api/auth/token/refresh/, retries the original request. Single in-flight refresh shared across concurrent 401s. (#107)
  • CLI: provider API keys now persisted via OS keychain (keyring package) on macOS / Windows / Linux Secret Service. ~/.clone/secrets.json (mode 0600) used when keychain is unreachable; existing entries auto-migrated to keychain on first re-login. (#108)

Schema & recording

  • EVENT_TYPE_CHOICES extended with input.keystroke, input.click, input.scroll to mirror packages/schema/events.schema.json and the desktop pipeline. (#96)
  • RecordingSession lookup is now (id, user)-scoped with explicit IntegrityError handling on cross-tenant collisions. (#96)
  • promote_memory cron cohort = RecordingEvent ∪ RawMemory — users whose recent activity already lives in RawMemory (CLI push, backfill jobs) are no longer silently skipped. (#90)

MCP surface

  • 10 tools, up from 3: predict_next_prompt, submit_feedback, list_predictions, get_prediction, get_user_context, start_session, stop_session, record_agent_prompt, record_agent_response, record_event. (#83, #84, #85)
  • eventSchema.source constrained to the canonical enum; helpers accept an optional source override (default 'agent'). (#104)
  • HTTP transport init race closed: createServer runs first, connect is wrapped in try/catch with explicit transport cleanup on failure. (#94)

Desktop

  • captureFlags (screen / keyboard / mouse) now plumbed through preload + IPC and gate the recording channels at the source. The Recording panel toggles are no longer UI theater. (#93)
  • Session IDs include a CSPRNG suffix (session_<ms>_<6-hex>); two starts in the same millisecond produce distinct files. (#101)
  • EventLog flushes to disk every 50 appends and on graceful close, with fsync on the underlying fd. SIGKILL / power-loss bound at-most-loss to ~1–2 seconds. (#102)

CLI

  • Local daemon hard-clamped to loopback; CLONE_DAEMON_HOST=0.0.0.0 is coerced to 127.0.0.1 with a stderr warning. (#91)
  • Single-flight spawn lock (fcntl.flock on POSIX) closes the race where two concurrent invocations both Popen a daemon. (#103)
  • Recording log shows the real session_id instead of a freshly minted UUID. (#92)

Web

  • Console.tsx default tab is Semantic Memories in production builds; the legacy mock Chat tab is dev-only. (#88)
  • SourcesView no longer fakes "live" counters via Math.random every 5s. (#89)
  • Signup URL-encodes the invite token; AccessControlView token uses crypto.randomUUID; Console search aborts stale fetches via AbortController and shows transport errors. (#100)

2026-05-05

  • Documentation site bootstrap. This site (apps/docs) is live at https://clone.is/docs. (commit bc210ac)
  • api.clone.is accepted on nginx server_name. (commit bc210ac)
  • Static MCP server card at /.well-known/mcp/server-card.json for Smithery. (commit 68f0679)

2026-04-01 → 2026-05-04

Detailed history in git log --oneline main. Highlights:

  • Recording / Memory / Prediction layers split into their own Django apps.
  • MCP server (apps/mcp) shipped with stdio + Streamable HTTP transports.
  • Web marketing site rebuilt on Vite + React 19 + Tailwind v4.