Operations

Markdown

Changelog

Product history for Externa Core (what operators install). Newest first. Sourced from GitHub Releases, CHANGELOG.md, and closed milestone issues.

Prefer fresh installs or follow Upgrade. After 1.0.0, Public API / GraphQL follow API 1.x compatibility.

Docs site

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

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–#186):

  • Schema changes — type / translatable locks with stored values are current behaviour (core #219 / PR #265); conversion tooling still core#220
  • Webhooks / scheduling — item.publish_failed + schedule_error / schedule_failed_at on Approvals and Content versioning (PR #303)
  • Public CMS API / GraphQL — PATCH / updateItem are partial updates (PR #293)
  • AuthZ — super-admin escalation guard + collection grants fail closed (PRs #307, #312)
  • Files / Docker / security — SSI/markup denylist + /storage/ CSP sandbox (PR #314); .dockerignore build-context note (PR #294)
  • API abuse controls — key scopes on ?include=, response cache, and Files read_only (PR #321)
  • Reverse proxy — TRUSTED_PROXIES applied from 1.3.0 (PR #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)
  • Earlier Unreleased sync — project settings split (core#201 / PR #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)

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 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
  • 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

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.

TopicDocsCore
Editorial approvalsApprovals#48 / docs #75
Translation workspaceTranslation workspace#49 / docs #76
Collection layoutsCollection layouts#47 / docs #77
Slack / TelegramIntegrations#39 / docs #78
Collaborative editingCollaborative editing#50 / docs #80
MeilisearchMeilisearch sync#40 / docs #81
Git exportGit export sync#41 / docs #82
CMS importCMS import connectors#30 / docs #83
SSO / OIDCSSO / OIDC#29 / docs #84

1.1.7 — OpenAPI from Core

1.1.6 — scheduled publish

1.1.5 — content versioning UX

1.1.4 — live preview

1.1.3 — headless starter

1.1.2 — webhooks recipes

  • Outbound webhooks — delivery status in admin, Make / n8n / Zapier recipes, Vercel/Netlify build-hook notes (core #35) — Outbound webhooks

Externa Core

1.2.2 — 2026-10-22

Security patch from release/1.2.2 (#250).

Fixes

  • externa:install keeps or generates APP_KEY, migrates the minimal profile without Redis, and can be re-run with --force (#249, #245) — Installation

Security

  • Official Docker image on php:8.4.27-fpm-bookworm with hardened php.ini; Composer php constraint raised to ^8.4.27 (#248, #216) — discussion #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, #185) — AI API

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 and 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.

1.2.1 — 2026-10-21

Hotfix from hotfix/1.2.1 (#223).

Fixes

  • Renaming a field no longer drops its value from pending drafts and older revisions (#218) — 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 · Schema changes
  • Docker: pin ghcr.io/qiick-io/externa-core:1.2.1 (or jump to 1.2.2).

1.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) — Editorial approvals
  • Translation workspace: side-by-side source/target locales on the item form, copy helpers, completeness (#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
  • 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) — Translation workspace
  • List layouts: optional kanban (select/radio field) and calendar (date field); table stays the default (#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) — Collection layouts
  • Presence + soft lock: avatars of co-editors, a 30 s soft lock, and stale-save protection via expected_updated_at (#50) — Collaborative editing

Integrations

Auth

  • OIDC / SSO login (Socialite + issuer discovery): link by verified email, JIT provisioning off by default, login button alongside password/passkey (#29) — SSO / OIDC

Starters

Fixes

  • Meilisearch: the index is created with primaryKey=id; before this fix documents were silently not indexed (#179)
  • Git export: clones use --template= (works on sandboxed filesystems) and empty bare remotes are bootstrapped (#179, #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)
  • Telegram test in Project settings runs synchronously, shows Bot API errors, and validates the BotFather token format (#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)

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 — 2026-10-01

First post-GA cut. Milestone: 1.1.0.

  • 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 — 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.

Security

  • Outbound webhooks — refuse delivery when signing secret empty (no empty-key HMAC) (#88)
  • AuthZ map — surface → gate → Pest coverage for admin, Public CMS API, GraphQL, AI, webhooks, private files (#90) — 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) — Deploy with Docker

Files / DX

  • FileChunkUploadService extract from FileService (#89)

Docs site for this cut: 1.1.1. Related: Packagist, Releasing, GA readiness, Security checklist.


1.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.

Security

  • Private files — effective-private bytes on private_assets (not public symlink) (#84)
  • Upload denylist — block SVG / HTML / HTM (#85)
  • AI collection-import webhook — HMAC over body + collection_id (#86)

Install & release

  • create-project — post-scripts stay minimal; handoff to externa:install (#93)
  • npm prepare / Lefthook — no-op without .git so Docker image-build stays green (#94)
  • Who ships — maintainers merge/tag/Release; agents open release PRs only (#92) — Releasing

Docker

  • phpredis pin — 6.3.0 from GitHub tarball (bypass flaky pecl install redis on multi-arch bake)
  • Dependency refresh within constraints (#95); Larastan level 5 + baseline (#87)

Packagist lists 1.0.0-beta.4. Docs pages: Files configuration, File Manager — upload security, AI API, Packagist, Contributing — Lefthook.


1.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. Milestone: 1.0.0-beta.3.

Install & upgrade

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

Docker & ops

  • Multi-arch images — linux/amd64 + linux/arm64 bake (#14)
  • Managed Compose profile — app + workers only; external DB/Redis (#15)
  • Reverse proxy cookbook — Caddy / Traefik / nginx, TLS, Reverb WebSockets (#17)
  • Dev Container — one-click VS Code / Codespaces stack (#18)

AI & DX

  • Embeddings for SearchSimilar — real embeddings when a provider is configured (#9)
  • ManageRoles duplicate — AI tool can clone roles like the admin UI (#10)

Security & CI

  • Composer / npm audit on PRs and main branches (#32)
  • Dependabot for Composer and npm (#33)
  • CodeQL + secret scanning hygiene for the public repo (#34)
  • Lefthook / commitlint — optional local hooks; CI remains source of truth (#31)

Docs & release process

  • Release process — CHANGELOG, semver, version bump, GitHub Releases (#22)
  • API & GraphQL 1.x compatibility policy (#23)
  • GA groundwork — security checklist pass, perf smoke, support window notes (#11)

Docs pages for this cut: Packagist, Upgrade, Backup & restore, Deployment, Reverse proxy, Production without Redis, Releasing, API compatibility, GA readiness.


1.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. Compare: v1.0.0-beta.1...v1.0.0-beta.2. Milestone: 1.0.0-beta.2.

Docker & ops

  • Local + production Compose — compose.yaml, compose.prod.yaml, multi-stage Dockerfile, Docker CI (#12, PR #55)
  • Health probes — GET /health/live and GET /health/ready for LB / Compose (#13)
  • S3 / MinIO file storage — FILES_DISK + Flysystem AWS S3 adapter for multi-instance uploads (#16)

Databases & CI

  • MySQL 8+ / MariaDB 10.6+ — first-class CI matrix + docs (#5)
  • PostgreSQL Pest job — production-leaning driver in CI (#6, PR #53)

Features

  • Duplicate non-system roles — clone Spatie permissions + matrices (#2, PR #52)
  • Branded transactional email — logo / project_color / name from Appearance (#21, PR #54)

Docs

  • README product narrative + UI screenshots (#3, PR #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.


1.0.0-beta.1 — 2026-09-13

First public beta. Milestone issues were thin (release cut only); history below is from the GitHub Release, CHANGELOG.md, and PR #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)

PHP8.4+
Node24
DBSQLite (default), MySQL, or Postgres
RedisOptional — 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 tagNotes
1.1.4 (this cut)Live Preview URL templates + signed token docs (#42)
1.1.3Headless Next.js starter page (#36)
1.1.2Webhooks delivery UX + Make/n8n/Zapier / build-hook recipes (#35)
1.1.1SEO/canonical fix, docs footer (Privacy + credit), dependency refresh
1.1.0Docs parity for Core v1.0.0 GA + beta.4 narrative
v1.0.4Docs for Core v1.0.0-beta.3 (+ post-cut security/ops on develop)
v1.0.3Docs for Core beta.2 ops (Docker, health, S3, multi-DB, …)
v1.0.2Docs aligned with Core v1.0.0-beta.1
Earlierv1.0.1, v1.0.0 — site bootstrap

How maintainers cut Core releases: Releasing & versions.