# Changelog

Source: https://docs.externa.qiick.io/docs/changelog

Product history for **Externa Core** (what operators install). Newest first. Sourced from [GitHub Releases](https://github.com/qiick-io/externa-core/releases), [`CHANGELOG.md`](https://github.com/qiick-io/externa-core/blob/main/CHANGELOG.md), and closed milestone issues.

> **Related**
> [Releasing & versions](/docs/releasing) · [Upgrade](/docs/upgrade) · [API 1.x compatibility](/docs/api-compatibility) · [GA readiness](/docs/ga-readiness) · Core project board: [qiick-io/projects/1](https://github.com/orgs/qiick-io/projects/1)

> Prefer fresh installs or follow [Upgrade](/docs/upgrade). After `1.0.0`, Public API / GraphQL follow [API 1.x compatibility](/docs/api-compatibility).

## Docs site

### 1.4.0 — externa-core 1.4.0 documentation (2026-11-10)

- **New pages** — [MCP server](/docs/mcp-server) and [AI tool approvals & audit](/docs/ai-tool-approvals) ([core#121](https://github.com/qiick-io/externa-core/issues/121), [#202](https://github.com/qiick-io/externa-core/issues/202), [#203](https://github.com/qiick-io/externa-core/issues/203)); [Image transforms](/docs/image-transforms) for named presets, Public API `/api/v1/files/{id}/transforms/{key}` / `size-{n}`, caching, focal point, and a Next.js `<Image>` loader ([core#123](https://github.com/qiick-io/externa-core/issues/123))
- **AI** — assistant context attachments, saved prompts, Agent Skills, write tools denied by default with chat read actions kept ([AI chat](/docs/ai-chat), [AI assistant model](/docs/ai-assistant), [AI configuration](/docs/ai-configuration))
- **Public API** — batch item writes, system-column and depth-1 relational filters, `sort`, Live Preview `as_of`, API key `files_scope` / owner / scopes, `@qiick/externa-sdk` (not published yet) ([Public CMS API](/docs/public-cms-api), [API abuse controls](/docs/api-abuse-controls), [Live Preview](/docs/live-preview))
- **Admin & ops** — deploy hooks, theme presets and brand focus-ring contrast, field conversion (`externa:field-convert`), GCS / Azure file disks, upload allowlist + SVG opt-in, security headers, server-side i18n, accessibility CI gates ([Project settings](/docs/project-settings), [Schema changes](/docs/schema-changes), [Files & storage](/docs/files-configuration), [Application config](/docs/configuration), [Accessibility](/docs/accessibility))
- **UI rebuild & AI transparency** — answers show reasoning, tool calls, sources and token usage, persisted across reloads ([AI chat — What an answer shows](/docs/ai-chat#what-an-answer-shows)); Assistant provider, reasoning effort and context window settings ([AI configuration](/docs/ai-configuration#assistant-provider-reasoning-and-context-window-1-4-0)); chat reactions, user hover cards, reply quotes, pinned messages, attachment cards and photos in bubbles ([Chat](/docs/chat#in-the-thread-1-4-0)); square file cards and click-to-set focal point ([File manager](/docs/file-manager#grid-and-details-panel-1-4-0)); server-driven admin tables ([Users & groups — Admin lists](/docs/users-and-groups#admin-lists-1-4-0))
- **Assistant answers as shipped** — tool calls as sentences grouped under "Done in N steps", reasoning that opens while the model thinks, the approval card (Approve red only for deletes), new AI chat screenshots ([AI chat](/docs/ai-chat)); the collection-import webhook examples sign `"{timestamp}.{rawBody}"` with `X-AI-Webhook-Timestamp` ([AI API](/docs/ai-api))
- **Reference** — all new env keys in [Environment variables](/docs/environment-variables); [Upgrade — 1.3.x → 1.4.0](/docs/upgrade#1-3-x-1-4-0) with steps, automatic backfills, behaviour changes, and the PostgreSQL 15 requirement

### 1.3.10 — Core 1.3.0 gaps closed (2026-10-28)

Closes remaining externa-core **v1.3.0** documentation gaps and ships prior Unreleased sync (docs [#182](https://github.com/LucaGiardi20/externa-docs/pull/182)–[#186](https://github.com/LucaGiardi20/externa-docs/pull/186)):

- **Schema changes** — type / translatable locks with stored values are current behaviour (core [#219](https://github.com/qiick-io/externa-core/issues/219) / [PR #265](https://github.com/qiick-io/externa-core/pull/265)); conversion tooling still [core#220](https://github.com/qiick-io/externa-core/issues/220)
- **Webhooks / scheduling** — `item.publish_failed` + `schedule_error` / `schedule_failed_at` on Approvals and Content versioning ([PR #303](https://github.com/qiick-io/externa-core/pull/303))
- **Public CMS API / GraphQL** — `PATCH` / `updateItem` are partial updates ([PR #293](https://github.com/qiick-io/externa-core/pull/293))
- **AuthZ** — super-admin escalation guard + collection grants fail closed ([PRs #307](https://github.com/qiick-io/externa-core/pull/307), [#312](https://github.com/qiick-io/externa-core/pull/312))
- **Files / Docker / security** — SSI/markup denylist + `/storage/` CSP sandbox ([PR #314](https://github.com/qiick-io/externa-core/pull/314)); `.dockerignore` build-context note ([PR #294](https://github.com/qiick-io/externa-core/pull/294))
- **API abuse controls** — key scopes on `?include=`, response cache, and Files `read_only` ([PR #321](https://github.com/qiick-io/externa-core/pull/321))
- **Reverse proxy** — `TRUSTED_PROXIES` applied from 1.3.0 ([PR #295](https://github.com/qiick-io/externa-core/pull/295))
- **Upgrade** — 1.2.x → 1.3.0 steps (migrate schedule columns, `AI_WEBHOOK_TOKEN`, Docker `1.3.0`, OpenAPI in `--no-dev` images [PR #310](https://github.com/qiick-io/externa-core/pull/310))
- **Earlier Unreleased sync** — project settings split ([core#201](https://github.com/qiick-io/externa-core/issues/201) / [PR #304](https://github.com/qiick-io/externa-core/pull/304)); AI webhook fail-closed + rotate (core#185 / #207); CI audits (core#184); raw-SQL PHPStan allowlist (core#208); AuthZ regression suite link (core#114)

### Security notice — PHP emergency releases (21 Oct 2026)

- **PHP CVEs (not in Externa)** — minimum safe patch versions are **8.4.27** / **8.5.12**. From externa-core **1.2.2**, Composer requires `php: ^8.4.27`. Official GHCR `1.2.2` / `latest` ship PHP 8.4.27 — re-pull containers. Full announcement: [externa-core discussion #247](https://github.com/qiick-io/externa-core/discussions/247). Operator pages: [Installation](/docs/installation), [Deploy with Docker](/docs/deploy-with-docker), [Upgrade](/docs/upgrade), [Security checklist](/docs/security-checklist).

### 1.3.9 — Core 1.3.0 SSRF / MIME upgrade notes (2026-10-25)

- **Upgrade / security** — documented externa-core **1.3.0** webhook SSRF hardening (`WEBHOOKS_ALLOW_PRIVATE_HOSTS`), MIME allowlist updates, and related breaking notes across Upgrade, Webhooks, Environment variables, File manager, Files configuration, Threat model, and Security checklist (docs #169, core #118 / PR #267)

### 1.3.8 — Why the name Externa? (2026-10-23)

- **Introduction** — home page callout on the Latin etymology of _Externa_, the client origin of the name, and the outward-facing bow-tie mark (docs #165, #166)

### 1.3.7 — Externa mark v3 (2026-10-22)

- **Brand** — the docs now use the Externa mark v3 (teal bow-tie) in the header logo, favicon, app and Apple touch icons, the Open Graph image and the README headers (docs #161)

### 1.3.6 — Locale fallback chain (2026-10-22)

- **Locales** — new [Configuration — Locale fallback](/docs/configuration#locale-fallback) section: active locale resolution vs the value fallback chain (requested → enabled `fallback_content_locales` → `APP_FALLBACK_LOCALE` if enabled → `null`), empty strings treated as missing, and how editing Content languages rewrites the stored chain; cross-links from Collections data model, Public CMS API, Project settings, Field types and Live Preview. Live Preview active-locale step 5 corrected to `APP_LOCALE` (docs #157, closes #133)

### 1.3.5 — Installer anchor fix (2026-10-22)

- **Links** — the `externa:install` links on the Upgrade, Changelog and Packagist pages now point to the correct Installation section (`#interactive-installer-externa-install`) (docs #153)

### 1.3.4 — externa-core 1.2.1 and 1.2.2 (2026-10-22)

- **Upgrade** — new `1.2.0 → 1.2.1` and `1.2.1 → 1.2.2` sections; Docker examples pin `ghcr.io/qiick-io/externa-core:1.2.2` (docs #149)
- **Schema changes** — field renames are safe from core 1.2.1; new "Repairing older drafts" section for `php artisan externa:repair-renamed-field-drafts` (dry run, `--apply`, `--map=collection:old=new`) (docs #149)
- **PHP security** — externa-core 1.2.2 requires `php: ^8.4.27`; official GHCR `1.2.2` / `latest` ship PHP 8.4.27 (docs #149)
- **AI webhook** — collection-import HMAC is over the raw body only and returns **401** on failure or when `AI_WEBHOOK_TOKEN` is unset outside `local` (core 1.2.2) across AI, AuthZ, routing, threat model and security checklist pages (docs #149)
- **Installer** — `externa:install` keeps or generates `APP_KEY`, runs the minimal profile without Redis, and can be re-run with `--force` (core 1.2.2) (docs #149)
- **Changelog** — Externa Core 1.2.1 and 1.2.2 entries (docs #149)

### 1.3.3 — Accessibility, qiick theme, and core 1.2.1 content (2026-10-22)

- **Accessibility** — WCAG 2.2 AA pass with 0 axe violations in light and dark: `<main>` landmark, skip link, labelled logo and dialogs, contrast fixes, and dead localhost/private-repo links removed (docs #136)
- **Theme and icons** — qiick semantic theme tokens (layout unchanged) and Lucide icons instead of inline SVGs (docs #142)
- **PHP security** — PHP 8.4.27+ / 8.5.12+ required after the October 2026 PHP advisories, plus a notice on the operator pages that the official GHCR `1.2.1` / `latest` images were rebuilt on PHP 8.4.27 (docs #143, #145)
- **Translation workspace** — matches the externa-core `1.2.1` locale UI (docs #144)
- **Live preview** — draft vs published response shapes, preview auth with allowed origins, and locale resolution (docs #138)
- **Field types** — collection pack block schema and nested block locale behaviour (docs #139)
- **Schema changes** — new page on renaming fields and changing types with existing content (docs #140)
- **Files** — thumbnail max size corrected from 256 to 512 px (docs #137)
- **Repo** — qiick brand header in the README and agent UI rules in `AGENTS.md` / `CLAUDE.md` (docs #130, #135)

### 1.3.2 — Canonical Externa URLs

- **Links** — marketing links now point to the canonical website `https://externa.qiick.io/en` and docs `https://docs.externa.qiick.io/` (GA readiness, Headless starter, Website ↔ docs messaging), and the JSON-LD `SoftwareApplication.url` uses the EN home page (docs #117)

### 1.3.1 — Chrome Ask the docs fix + AI coding tools page

- **Ask the docs (Chrome built-in)** — separate Prompt API sessions for rewrite and answer, English output for Gemini Nano, `inputQuota` fitting, passage fallback for stub replies, and an English unverified banner outside answer markdown (docs #112)
- **Using Externa with AI coding tools** — new Getting started page for Context7 library IDs (`/qiick-io/externa-core`, `/llmstxt/externa_qiick_io_llms_txt`), MCP setup, and `llms.txt` / `llms-full.txt` (docs #113); Context7 snippet counts omitted so they do not drift on reindex
- **Core 1.2.0 docs gap** — AI translate, collection layouts, upgrade notes, and related pages aligned with externa-core `v1.2.0` (docs #111)
- **CI** — cache the MiniLM Transformers.js model between Actions runs (docs #110)

### 1.3.0 — Ask the docs (in-browser AI assistant)

- **Ask the docs** — optional on-device assistant: chat runs in the browser via WebLLM or the built-in Prompt API, with no server-side inference; shown only on capable browsers (docs #105)
- **Semantic search** — MiniLM embeddings built at build time (`/search/embeddings.v1.json`) with query expansion and source ranking; answers link to the matching pages (docs #105)
- **Safe rendering** — model output rendered through a hardened Markdoc pipeline (docs #105)

### 1.2.0 — SEO, AI Markdown, security, and performance

- **Security** — `next` 16.4.2 + `sharp` ≥0.35.5; production `npm audit --omit=dev` clean of high/critical (docs #95)
- **SEO metadata & sitemap** — restore `og:image` on all pages, branded homepage title, unique sitemap URLs with per-page `lastmod` (docs #96)
- **AI discoverability** — `/llms.txt`, `/llms-full.txt`, and `/docs/<slug>.md` Markdown mirrors (docs #97)
- **Index hygiene** — noindex maintainer pages, docs→website links, sidebar headings no longer precede page `h1` (docs #98)
- **Structured data** — per-page `TechArticle` + `BreadcrumbList` JSON-LD linked to marketing-site entities (docs #99)
- **Performance** — CSS hero glows, optimized screenshots, lazy search dialog, contrast fixes (docs #100)

### 1.1.16 — notifier filters + core 1.1.0/1.2.0 sync

- **Notifier event filters** — per-project muting of event types (`notifier_event_types`) documented in [Project settings](/docs/project-settings)
- **Core 1.1.0 / 1.2.0 docs sync** — changelog, environment variables, headless starter, project settings, upgrade and webhooks pages updated (docs #88)

### 1.1.15 — starters + ops guides

- **Nuxt headless starter** — [Headless starter](/docs/headless-starter) + [qiick-io/externa-nuxt-starter](https://github.com/qiick-io/externa-nuxt-starter) ([core #152](https://github.com/qiick-io/externa-core/issues/152))
- **Starter conventions** — multi-repo checklist ([core #156](https://github.com/qiick-io/externa-core/issues/156))
- **Performance tuning** — Public API cache, `include`s, queues, Pulse (docs #49) — [Performance tuning](/docs/performance-tuning)
- **Website ↔ docs messaging** — GA feature matrix (docs #50) — [Website ↔ docs messaging](/docs/website-docs-messaging)
- **Docs sync epic** — nav/changelog confirmed for core 1.1.0 feature set (docs #48)

### 1.1.14 — core 1.2.0 companion

Companion docs for **externa-core 1.2.0**: editorial approvals, translation workspace, kanban/calendar layouts, Slack/Telegram notifiers, collaborative presence, Meilisearch, git export, CMS import connectors, SSO/OIDC.

| Topic                 | Docs                                                 | Core                                                                 |
| --------------------- | ---------------------------------------------------- | -------------------------------------------------------------------- |
| Editorial approvals   | [Approvals](/docs/approvals)                         | [#48](https://github.com/qiick-io/externa-core/issues/48) / docs #75 |
| Translation workspace | [Translation workspace](/docs/translation-workspace) | [#49](https://github.com/qiick-io/externa-core/issues/49) / docs #76 |
| Collection layouts    | [Collection layouts](/docs/collection-layouts)       | [#47](https://github.com/qiick-io/externa-core/issues/47) / docs #77 |
| Slack / Telegram      | [Integrations](/docs/integrations)                   | [#39](https://github.com/qiick-io/externa-core/issues/39) / docs #78 |
| Collaborative editing | [Collaborative editing](/docs/collaborative-editing) | [#50](https://github.com/qiick-io/externa-core/issues/50) / docs #80 |
| Meilisearch           | [Meilisearch sync](/docs/meilisearch)                | [#40](https://github.com/qiick-io/externa-core/issues/40) / docs #81 |
| Git export            | [Git export sync](/docs/git-export)                  | [#41](https://github.com/qiick-io/externa-core/issues/41) / docs #82 |
| CMS import            | [CMS import connectors](/docs/cms-import)            | [#30](https://github.com/qiick-io/externa-core/issues/30) / docs #83 |
| SSO / OIDC            | [SSO / OIDC](/docs/sso-oidc)                         | [#29](https://github.com/qiick-io/externa-core/issues/29) / docs #84 |

### 1.1.7 — OpenAPI from Core

- **OpenAPI serve** — document `GET /api/v1/openapi.json` + YAML sync policy ([core #25](https://github.com/qiick-io/externa-core/issues/25)) — [Public CMS API client types](/docs/public-cms-api-types)

### 1.1.6 — scheduled publish

- **Scheduled publish / unpublish** — item datetime + `collections:process-schedules` ([core #44](https://github.com/qiick-io/externa-core/issues/44)) — [Content versioning](/docs/content-versioning)

### 1.1.5 — content versioning UX

- **Content versioning & revisions** — draft/publish badges, promote/discard, list filter ([core #43](https://github.com/qiick-io/externa-core/issues/43)) — [Content versioning](/docs/content-versioning)

### 1.1.4 — live preview

- **Live Preview** — URL templates, signed token, `GET /api/v1/preview` ([core #42](https://github.com/qiick-io/externa-core/issues/42)) — [Live Preview](/docs/live-preview)

### 1.1.3 — headless starter

- **Headless starter** — official Next.js App Router starter against Public CMS API ([core #36](https://github.com/qiick-io/externa-core/issues/36)) — [Headless starter](/docs/headless-starter) · [qiick-io/externa-next-starter](https://github.com/qiick-io/externa-next-starter)

### 1.1.2 — webhooks recipes

- **Outbound webhooks** — delivery status in admin, Make / n8n / Zapier recipes, Vercel/Netlify build-hook notes ([core #35](https://github.com/qiick-io/externa-core/issues/35)) — [Outbound webhooks](/docs/webhooks)

## Externa Core

### [1.2.2](https://github.com/qiick-io/externa-core/releases/tag/v1.2.2) — 2026-10-22

Security patch from `release/1.2.2` ([#250](https://github.com/qiick-io/externa-core/pull/250)).

#### Fixes

- `externa:install` keeps or generates `APP_KEY`, migrates the minimal profile without Redis, and can be re-run with `--force` ([#249](https://github.com/qiick-io/externa-core/pull/249), [#245](https://github.com/qiick-io/externa-core/issues/245)) — [Installation](/docs/installation#interactive-installer-externa-install)

#### Security

- Official Docker image on `php:8.4.27-fpm-bookworm` with hardened `php.ini`; Composer `php` constraint raised to `^8.4.27` ([#248](https://github.com/qiick-io/externa-core/pull/248), [#216](https://github.com/qiick-io/externa-core/issues/216)) — [discussion #247](https://github.com/qiick-io/externa-core/discussions/247)
- AI collection-import webhook: timing-safe HMAC-SHA256 over the **raw body** (`hash_equals`); fail-closed when `AI_WEBHOOK_TOKEN` is unset outside `local`; **401** on mismatch ([#214](https://github.com/qiick-io/externa-core/pull/214), [#185](https://github.com/qiick-io/externa-core/issues/185)) — [AI API](/docs/ai-api#webhook-hmac-auth)

#### Upgrade notes

- Docker: pin `ghcr.io/qiick-io/externa-core:1.2.2` (or `latest`). Source installs: PHP **8.4.27+** (or **8.5.12+**) and disable `session.upload_progress` — see [Installation](/docs/installation) and [Deploy with Docker](/docs/deploy-with-docker).
- Webhook signers must sign the raw request body only (`sha256=` + HMAC-SHA256). Set `AI_WEBHOOK_TOKEN` in every non-local environment. Invalid signatures return **401** (was 403).
- See [Upgrade — 1.2.1 → 1.2.2](/docs/upgrade#1-2-1-1-2-2).

### [1.2.1](https://github.com/qiick-io/externa-core/releases/tag/v1.2.1) — 2026-10-21

Hotfix from `hotfix/1.2.1` ([#223](https://github.com/qiick-io/externa-core/pull/223)).

#### Fixes

- Renaming a field no longer drops its value from pending drafts and older revisions ([#218](https://github.com/qiick-io/externa-core/issues/218)) — [Schema changes](/docs/schema-changes)

#### Security

- Lockfile bumps: `follow-redirects` 1.16.1, `vite` 8.3.5 (via `launch-editor`; `package.json` range `^8.3.5`), `brace-expansion` 1.1.21 (dev); `npm audit --audit-level=high` reports 0 high/critical

#### Upgrade notes

- Run `php artisan externa:repair-renamed-field-drafts` (dry run, then `--apply`) right after deploying, before the scheduler runs or anyone publishes — [Upgrade](/docs/upgrade#1-2-0-1-2-1) · [Schema changes](/docs/schema-changes#repairing-older-drafts)
- Docker: pin `ghcr.io/qiick-io/externa-core:1.2.1` (or jump to **1.2.2**).

### [1.2.0](https://github.com/qiick-io/externa-core/releases/tag/v1.2.0) — 2026-10-18

Editorial + integrations cut. Everything new is **opt-in**: off by default, no behavior change until enabled.

#### Editorial

- **Approvals workflow**: per-collection `approvals_required` (versioned collections only), submit / approve / reject with a note, publish gated on approval, webhook events `item.submitted` / `item.approved` / `item.rejected`, permissions `can-submit-collections` / `can-approve-collections` ([#48](https://github.com/qiick-io/externa-core/issues/48)) — [Editorial approvals](/docs/approvals)
- **Translation workspace**: side-by-side source/target locales on the item form, copy helpers, completeness ([#49](https://github.com/qiick-io/externa-core/issues/49)) — note: the side-by-side Translate mode did not ship; 1.2.0 / 1.2.1 use the locale dropdown + per-field helpers described on [Translation workspace](/docs/translation-workspace)
- **AI field translation** on the item form: **Translate with AI from {locale}** fills translatable target fields using the local AI provider (`POST /ai/translate-fields`, `ContentTranslator`) ([#193](https://github.com/qiick-io/externa-core/pull/193)) — [Translation workspace](/docs/translation-workspace)
- **List layouts**: optional kanban (select/radio field) and calendar (date field); table stays the default ([#47](https://github.com/qiick-io/externa-core/issues/47)). Kanban columns lazy-load and card order persists via `board_sort`; the calendar adds Month / Week / Day / List views and drag-to-reschedule; the items-list toolbar gains filters ([#193](https://github.com/qiick-io/externa-core/pull/193)) — [Collection layouts](/docs/collection-layouts)
- **Presence + soft lock**: avatars of co-editors, a 30 s soft lock, and stale-save protection via `expected_updated_at` ([#50](https://github.com/qiick-io/externa-core/issues/50)) — [Collaborative editing](/docs/collaborative-editing)

#### Integrations

- **Slack / Telegram notifiers** on the domain event bus, with an event-type filter and a test button ([#39](https://github.com/qiick-io/externa-core/issues/39)) — [Slack & Telegram notifiers](/docs/integrations)
- **Meilisearch sync** of published items (queue jobs; no Scout/Algolia) ([#40](https://github.com/qiick-io/externa-core/issues/40)) — [Meilisearch sync](/docs/meilisearch)
- **Git export** of published items to a remote (JSON/Markdown, deploy key, dry-run) ([#41](https://github.com/qiick-io/externa-core/issues/41)) — [Git export sync](/docs/git-export)
- **CMS import profiles** `directus` / `wordpress` for the AI `ImportRemoteJson` tool ([#30](https://github.com/qiick-io/externa-core/issues/30)) — [CMS import connectors](/docs/cms-import)

#### Auth

- **OIDC / SSO login** (Socialite + issuer discovery): link by verified email, JIT provisioning off by default, login button alongside password/passkey ([#29](https://github.com/qiick-io/externa-core/issues/29)) — [SSO / OIDC](/docs/sso-oidc)

#### Starters

- Official **Nuxt** starter [qiick-io/externa-nuxt-starter](https://github.com/qiick-io/externa-nuxt-starter) + multi-repo starter conventions ([#152](https://github.com/qiick-io/externa-core/issues/152), [#156](https://github.com/qiick-io/externa-core/issues/156)) — [Headless starter](/docs/headless-starter)

#### Fixes

- Meilisearch: the index is created with `primaryKey=id`; before this fix documents were silently not indexed ([#179](https://github.com/qiick-io/externa-core/issues/179))
- Git export: clones use `--template=` (works on sandboxed filesystems) and empty bare remotes are bootstrapped ([#179](https://github.com/qiick-io/externa-core/issues/179), [#182](https://github.com/qiick-io/externa-core/issues/182))
- OIDC: callback validation errors redirect to login instead of looping back to the IdP; SSO rejection errors show on the login page
- AI translate updates React-controlled TipTap / markdown fields ([#193](https://github.com/qiick-io/externa-core/pull/193))
- Telegram test in Project settings runs synchronously, shows Bot API errors, and validates the BotFather token format ([#183](https://github.com/qiick-io/externa-core/issues/183))

#### Security

- OIDC client secret and Telegram bot token are stored encrypted
- npm lockfile bumps so `npm audit --omit=dev --audit-level=high` passes ([#182](https://github.com/qiick-io/externa-core/issues/182))

#### Upgrade notes

- Run `composer install` (adds `laravel/socialite` `^5.31`), then `npm ci && npm run build`, then `php artisan externa:upgrade` (or `migrate --force` + `permissions:sync`). New migrations: `collections.approvals_required`; `collections_items.approval_status` / `rejection_note` / `submitted_by` / `reviewed_by` / `reviewed_at`; `collections_items.board_sort` / `published_at`; `users.oidc_sub` (unique). **`users.password` becomes nullable.** Notifier mute list uses project setting `notifier_event_types` (null = all events).
- `permissions:sync` adds `can-submit-collections` / `can-approve-collections`. Assign them to roles before turning on approvals.
- Restart queue workers (Horizon) and Reverb — presence and the Meilisearch / git-export jobs depend on them. Without realtime, the item form works as before.
- Docker: pin `ghcr.io/qiick-io/externa-core:1.2.0`.

### [1.1.0](https://github.com/qiick-io/externa-core/releases/tag/v1.1.0) — 2026-10-01

First post-GA cut. Milestone: [1.1.0](https://github.com/qiick-io/externa-core/milestone/5).

- Live Preview, `GET /api/v1/preview` (#42) · Draft/publish UX, `has_draft` (#43) · Scheduled publish, `collections:process-schedules` (#44)
- OpenAPI `GET /api/v1/openapi.json` (#25) · webhook catalog + delivery log (#35) · Next.js starter (#36)
- Field conditions `contains`, `gt/gte/lt/lte`, `in/not_in`, OR (#45) · Activity export (#28) · a11y (#26) · i18n (#27)
- **Breaking:** `laravel/ai` ^1.0 changes the AI chat history schema, and destructive AI tools now require Approve/Reject (#144). Run `php artisan migrate`.

### [1.0.0](https://github.com/qiick-io/externa-core/releases/tag/v1.0.0) — GA

First stable GA. Builds on beta.4 security/install/Docker work plus AuthZ docs, outbound webhook secret enforcement, and Docker deploy DX. Milestone: [1.0.0](https://github.com/qiick-io/externa-core/milestone/4).

#### Security

- **Outbound webhooks** — refuse delivery when signing secret empty (no empty-key HMAC) ([#88](https://github.com/qiick-io/externa-core/issues/88))
- **AuthZ map** — surface → gate → Pest coverage for admin, Public CMS API, GraphQL, AI, webhooks, private files ([#90](https://github.com/qiick-io/externa-core/issues/90)) — [AuthZ map](/docs/authz-map)

#### Ops / Docker

- **Deploy with Docker** — GHCR multi-arch publish on `v*` tags, `compose.quick.yaml` pull path, gated `RUN_SEED` first-boot, healthchecks ([#56](https://github.com/qiick-io/externa-core/issues/56)) — [Deploy with Docker](/docs/deploy-with-docker)

#### Files / DX

- **FileChunkUploadService** extract from FileService ([#89](https://github.com/qiick-io/externa-core/issues/89))

Docs site for this cut: **`1.1.1`**. Related: [Packagist](/docs/packagist), [Releasing](/docs/releasing), [GA readiness](/docs/ga-readiness), [Security checklist](/docs/security-checklist).

---

### [1.0.0-beta.4](https://github.com/qiick-io/externa-core/releases/tag/v1.0.0-beta.4) — 2026-09-17

Last pre-GA beta: private files + upload denylist, AI webhook HMAC, minimal create-project handoff, Docker bake fixes, release ownership. Milestone: [1.0.0-beta.4](https://github.com/qiick-io/externa-core/milestone/7).

#### Security

- **Private files** — effective-private bytes on `private_assets` (not public symlink) ([#84](https://github.com/qiick-io/externa-core/issues/84))
- **Upload denylist** — block SVG / HTML / HTM ([#85](https://github.com/qiick-io/externa-core/issues/85))
- **AI collection-import webhook** — HMAC over body + `collection_id` ([#86](https://github.com/qiick-io/externa-core/issues/86))

#### Install & release

- **create-project** — post-scripts stay minimal; handoff to `externa:install` ([#93](https://github.com/qiick-io/externa-core/issues/93))
- **npm prepare / Lefthook** — no-op without `.git` so Docker `image-build` stays green ([#94](https://github.com/qiick-io/externa-core/issues/94))
- **Who ships** — maintainers merge/tag/Release; agents open release PRs only ([#92](https://github.com/qiick-io/externa-core/issues/92)) — [Releasing](/docs/releasing)

#### Docker

- **phpredis pin** — `6.3.0` from GitHub tarball (bypass flaky `pecl install redis` on multi-arch bake)
- Dependency refresh within constraints ([#95](https://github.com/qiick-io/externa-core/issues/95)); Larastan level 5 + baseline ([#87](https://github.com/qiick-io/externa-core/issues/87))

Packagist lists `1.0.0-beta.4`. Docs pages: [Files configuration](/docs/files-configuration), [File Manager — upload security](/docs/file-manager#upload-security), [AI API](/docs/ai-api), [Packagist](/docs/packagist), [Contributing — Lefthook](/docs/contributing#local-git-hooks-lefthook).

---

### [1.0.0-beta.3](https://github.com/qiick-io/externa-core/releases/tag/v1.0.0-beta.3) — 2026-09-16

Last beta before beta.4/GA: install/upgrade path, Docker ops depth, security CI, AI/DX, and release/API contracts. Release cut: [PR #77](https://github.com/qiick-io/externa-core/pull/77). Milestone: [1.0.0-beta.3](https://github.com/qiick-io/externa-core/milestone/3).

#### Install & upgrade

- **Packagist / create-project** — document `composer create-project` path for `qiick/externa-core` ([#7](https://github.com/qiick-io/externa-core/issues/7); Packagist org submit may still be pending)
- **Upgrade guide** — backup → fetch tag → Composer → migrate → permission sync → frontend rebuild; optional `externa:upgrade` ([#8](https://github.com/qiick-io/externa-core/issues/8))
- **Interactive installer** — guided `.env` + first-run setup via `externa:install` ([#4](https://github.com/qiick-io/externa-core/issues/4))
- **Backup & restore** — self-hosted runbook for DB, `storage/`, `.env`, S3/Docker notes ([#19](https://github.com/qiick-io/externa-core/issues/19))
- **Production without Redis** — database queue / degraded realtime path ([#20](https://github.com/qiick-io/externa-core/issues/20))

#### Docker & ops

- **Multi-arch images** — `linux/amd64` + `linux/arm64` bake ([#14](https://github.com/qiick-io/externa-core/issues/14))
- **Managed Compose profile** — app + workers only; external DB/Redis ([#15](https://github.com/qiick-io/externa-core/issues/15))
- **Reverse proxy cookbook** — Caddy / Traefik / nginx, TLS, Reverb WebSockets ([#17](https://github.com/qiick-io/externa-core/issues/17))
- **Dev Container** — one-click VS Code / Codespaces stack ([#18](https://github.com/qiick-io/externa-core/issues/18))

#### AI & DX

- **Embeddings for SearchSimilar** — real embeddings when a provider is configured ([#9](https://github.com/qiick-io/externa-core/issues/9))
- **ManageRoles duplicate** — AI tool can clone roles like the admin UI ([#10](https://github.com/qiick-io/externa-core/issues/10))

#### Security & CI

- **Composer / npm audit** on PRs and main branches ([#32](https://github.com/qiick-io/externa-core/issues/32))
- **Dependabot** for Composer and npm ([#33](https://github.com/qiick-io/externa-core/issues/33))
- **CodeQL + secret scanning** hygiene for the public repo ([#34](https://github.com/qiick-io/externa-core/issues/34))
- **Lefthook / commitlint** — optional local hooks; CI remains source of truth ([#31](https://github.com/qiick-io/externa-core/issues/31))

#### Docs & release process

- **Release process** — CHANGELOG, semver, version bump, GitHub Releases ([#22](https://github.com/qiick-io/externa-core/issues/22))
- **API & GraphQL 1.x compatibility policy** ([#23](https://github.com/qiick-io/externa-core/issues/23))
- **GA groundwork** — security checklist pass, perf smoke, support window notes ([#11](https://github.com/qiick-io/externa-core/issues/11))

Docs pages for this cut: [Packagist](/docs/packagist), [Upgrade](/docs/upgrade), [Backup & restore](/docs/backup-restore), [Deployment](/docs/deployment), [Reverse proxy](/docs/reverse-proxy), [Production without Redis](/docs/production-without-redis), [Releasing](/docs/releasing), [API compatibility](/docs/api-compatibility), [GA readiness](/docs/ga-readiness).

---

### [1.0.0-beta.2](https://github.com/qiick-io/externa-core/releases/tag/v1.0.0-beta.2) — 2026-09-16

Ops-first pre-release: Docker stacks, health probes, S3/MinIO-safe files, multi-DB CI, and product polish. Full notes: [GitHub Release](https://github.com/qiick-io/externa-core/releases/tag/v1.0.0-beta.2). Compare: [v1.0.0-beta.1...v1.0.0-beta.2](https://github.com/qiick-io/externa-core/compare/v1.0.0-beta.1...v1.0.0-beta.2). Milestone: [1.0.0-beta.2](https://github.com/qiick-io/externa-core/milestone/2).

#### Docker & ops

- **Local + production Compose** — `compose.yaml`, `compose.prod.yaml`, multi-stage `Dockerfile`, Docker CI ([#12](https://github.com/qiick-io/externa-core/issues/12), [PR #55](https://github.com/qiick-io/externa-core/pull/55))
- **Health probes** — `GET /health/live` and `GET /health/ready` for LB / Compose ([#13](https://github.com/qiick-io/externa-core/issues/13))
- **S3 / MinIO file storage** — `FILES_DISK` + Flysystem AWS S3 adapter for multi-instance uploads ([#16](https://github.com/qiick-io/externa-core/issues/16))

#### Databases & CI

- **MySQL 8+ / MariaDB 10.6+** — first-class CI matrix + docs ([#5](https://github.com/qiick-io/externa-core/issues/5))
- **PostgreSQL Pest job** — production-leaning driver in CI ([#6](https://github.com/qiick-io/externa-core/issues/6), [PR #53](https://github.com/qiick-io/externa-core/pull/53))

#### Features

- **Duplicate non-system roles** — clone Spatie permissions + matrices ([#2](https://github.com/qiick-io/externa-core/issues/2), [PR #52](https://github.com/qiick-io/externa-core/pull/52))
- **Branded transactional email** — logo / `project_color` / name from Appearance ([#21](https://github.com/qiick-io/externa-core/issues/21), [PR #54](https://github.com/qiick-io/externa-core/pull/54))

#### Docs

- **README product narrative + UI screenshots** ([#3](https://github.com/qiick-io/externa-core/issues/3), [PR #51](https://github.com/qiick-io/externa-core/pull/51))

#### Upgrade notes

- Compose app port defaults to **`:8000`** — set `COMPOSE_APP_URL` accordingly
- Prefer S3/MinIO via `FILES_DISK` for multi-container file storage
- Wire LB/Compose checks to `/health/live` and `/health/ready`
- Laravel Herd local workflow unchanged

Release cut: [PR #57](https://github.com/qiick-io/externa-core/pull/57).

---

### [1.0.0-beta.1](https://github.com/qiick-io/externa-core/releases/tag/v1.0.0-beta.1) — 2026-09-13

First public beta. Milestone issues were thin (release cut only); history below is from the [GitHub Release](https://github.com/qiick-io/externa-core/releases/tag/v1.0.0-beta.1), [`CHANGELOG.md`](https://github.com/qiick-io/externa-core/blob/main/CHANGELOG.md), and [PR #1](https://github.com/qiick-io/externa-core/pull/1).

#### Content & collections

- Dynamic collections with a broad field-type set (text, markdown/WYSIWYG, files, relations, blocks/M2A, map, conditions, layout groups)
- Item revisions, activity, advanced multi-rule filters, form layout (tabs / accordion / DnD)
- Collection/field packs and SEO-oriented expansion helpers

#### Files

- Hierarchical file manager (tags, previews, async duplicate/zip jobs)
- Upload denylist, text sanitization, private file access paths
- Public files API with role-gated grants

#### Auth, roles & security

- Spatie RBAC + groups with effective role inheritance
- Optional TOTP 2FA and Fortify passkeys (secure context required for WebAuthn)
- Project-level `two_factor_required`, bounded inputs, HTML sanitization
- Operator threat model + `SECURITY.md` (host owns TLS / backups / network)

#### APIs

- Public REST CMS API (`/api/v1`) with API keys and collection permission matrix
- Opt-in `?include=`, Origin allowlist / CORS, response cache controls
- GraphQL at `/api/graphql`
- Outbound webhooks

#### Collaboration

- Global chat hub: collection item threads + private/direct chats
- Unread, pins, attachments, realtime (Reverb/Echo when enabled)
- Per-user archive for private chats; notification mark-unread (no auto-read on drawer open)

#### Ops & admin UX

- Dashboard (activity, storage, upload health) + Health tab (Pulse/Horizon when enabled)
- Horizon / Reverb / Pulse wiring for the full stack; minimal stack runs without Redis
- i18n (en/it/de where shipped), project branding & appearance settings
- Optional AI assistant (OpenAI-compatible / LM Studio) scoped to the signed-in user’s permissions

#### Requirements (at cut)

|       |                                                                                 |
| ----- | ------------------------------------------------------------------------------- |
| PHP   | **8.4+**                                                                        |
| Node  | **24**                                                                          |
| DB    | SQLite (default), MySQL, or Postgres                                            |
| Redis | Optional — required for Horizon / Reverb-friendly realtime / Pulse redis ingest |

#### Known beta notes (at cut)

- Browser FileManager CI job is fail-soft (product Pest suite remains the hard gate)
- Dependabot findings on the default branch triaged after this cut
- Kitchen Sink / local QA seeders are **not** shipped in the OSS tree

---

## Docs site versions

This documentation site (`externa-docs`) versions separately from Core. Product features above always refer to **Externa Core** tags.

| Docs tag             | Notes                                                                 |
| -------------------- | --------------------------------------------------------------------- |
| **1.1.4** (this cut) | Live Preview URL templates + signed token docs (#42)                  |
| **1.1.3**            | Headless Next.js starter page (#36)                                   |
| **1.1.2**            | Webhooks delivery UX + Make/n8n/Zapier / build-hook recipes (#35)     |
| **1.1.1**            | SEO/canonical fix, docs footer (Privacy + credit), dependency refresh |
| **1.1.0**            | Docs parity for Core `v1.0.0` GA + beta.4 narrative                   |
| v1.0.4               | Docs for Core `v1.0.0-beta.3` (+ post-cut security/ops on develop)    |
| v1.0.3               | Docs for Core beta.2 ops (Docker, health, S3, multi-DB, …)            |
| v1.0.2               | Docs aligned with Core `v1.0.0-beta.1`                                |
| Earlier              | `v1.0.1`, `v1.0.0` — site bootstrap                                   |

How maintainers cut Core releases: [Releasing & versions](/docs/releasing).
