Release Notes
This page is a curated layer over the raw authoritative
CHANGELOG.md. For complete detail (including every Added/Changed/Removed/Fix line) consult the full changelog.
v1.85.3 - Alphard
Released: September 12, 2026
Patch: the boot environment is read the way env() reads everything else. Framework::create()
and console commands chose the environment from $_ENV['APP_ENV'] alone, so a process-exported
APP_ENV (a CI job, a container) was ignored: a CLI run booted as the wrong environment, skipped
its config/{env}/ overrides, and extensions:cache compiled the wrong provider list for whoever
booted next. The extension cache now records the environment it was compiled for and is not
consumed under another one outside production. Low risk: an exported value that was ignored is
honoured now, and older bare-list caches still load.
Migration Notes
- Skeleton bootstraps: pass
env('APP_ENV', 'development')towithEnvironment()instead of$_ENV['APP_ENV'] ?? 'development'. - Rebuild the extension cache on deploy as usual (
php glueful extensions:cache); the new file shape is read by this release and the bare-list shape remains readable.
composer update glueful/framework
v1.85.2 - Alphard
Released: September 12, 2026
Patch: env() sees variables the real process environment holds. It read $_ENV alone,
which PHP fills only when variables_order includes "E", and Dotenv skips keys the real
environment already holds — so a CI job or container exporting DB_* fell to the sqlite default
for a fresh install's first connections. env() now also reads $_SERVER and getenv(). Low
risk: a value that was invisible before is honoured now.
Migration Notes
- No action required. Tests that want a key absent must clear the real environment too
(
putenv('KEY')).
composer update glueful/framework
v1.85.1 - Alphard
Released: September 12, 2026
Patch: migrate:run adopts previous sources even with nothing pending. The command returned
at "No pending migrations found" before adoption ran, so an up-to-date database kept its rows
under a lane's previous source names. Low risk: only lanes declaring previous_sources are
affected.
Migration Notes
- No action required.
composer update glueful/framework
v1.85.0 - Alphard
Released: September 12, 2026
Minor: migrations can change owner without breaking existing databases. A migration lane may
declare the source names its files were recorded under before (previous_sources); rows under
those names count as applied and are adopted under the current source on the next run. Low risk:
an optional key, no behaviour change without it.
Key Highlights
previous_sources in the manifest, or from a provider
Adoption, scoped to what the lane ships
Migration Notes
- No action required. Use the key when your package takes over migrations previously recorded under another source: an application that became a package, a rename, a split lane.
composer update glueful/framework
v1.84.0 - Alnitak
Released: September 11, 2026
Minor: the API reference moves from /docs to /api-docs. The reference UI and its
openapi.json are served at the path in documentation.route_prefix (env API_DOCS_PATH), and
the default is now /api-docs, leaving /docs to your application's own documentation.
Moderate risk: links, bookmarks and tooling that used /docs need the new address, or set
API_DOCS_PATH=/docs to keep it.
Key Highlights
One setting, four consumers
Your /docs is yours
Migration Notes
- Update links to the reference (
/api-docs), or setAPI_DOCS_PATH=/docsto keep the old address. - Regenerate the UI page with
php glueful generate:openapi --ui: a page generated before 1.84.0 still loads/docs/openapi.json. - Mirror
API_DOCS_PATH=/api-docsinto your.env.exampleif you keep one.
composer update glueful/framework
v1.83.4 - Alnilam
Released: September 11, 2026
Patch: a mounted SPA document may frame itself and its own blob: documents. The document
CSP had no frame-src, so default-src 'self' applied and browsers refused an iframe pointing
at a blob: URL the page had minted itself — an admin previewing its own rendered output showed
nothing. Low risk: SPA document responses only; no third-party origin is allowed.
Key Highlights
frame-src 'self' blob: on the document policy
Migration Notes
- No action required. Mounts that pass their own
cspkeep it verbatim; addframe-src 'self' blob:to it if your SPA previews its own documents in an iframe.
composer update glueful/framework
v1.83.3 - Alnilam
Released: September 9, 2026
Patch: the production container is compiled once, atomically, under a signed name. Every PHP-FPM worker compiled the container on its own boot and rewrote one shared file before requiring it: a 783 KB write per request, workers requiring a half-written file ("Unclosed '{' on line 9557") and silently falling back to the runtime container, and — with OPcache not revalidating timestamps — workers executing whatever version they cached first, long after a deploy rewrote it. Low risk: the production boot path only.
Key Highlights
DefinitionSignature names the artifact
Atomic writes, signed precompiles
Migration Notes
- No action required. After updating, the first production boot compiles one signed artifact;
later boots require it. Re-run
php glueful di:container:compileif you rely on a precompiled container — the pre-1.83.3 file is unsigned and will be ignored.
composer update glueful/framework
v1.83.2 - Alnilam
Released: September 8, 2026
Patch: the Installer publishes freshly written database credentials to the running process.
A fresh create-project boots with the sample's placeholder credentials; the operator types real
ones at the provision prompt. They reached .env and the injected migration connection, but any
migration that opens its own connection still read the placeholders and failed with "role
your_database_user does not exist". Low risk: installer-only; nothing changes when .env
already held real credentials.
Key Highlights
ApplicationContext::forgetConfig()
Migration Notes
- No action required. Installed hosts are unaffected; fresh installs stop failing at migrate when credentials are entered at the prompt.
composer update glueful/framework
v1.83.1 - Alnilam
Released: September 8, 2026
Patch: production recommendations stop spamming the error log and stop degrading health.
PHP-FPM boots the framework on every request, so each applicable [security] RECOMMENDATION
(an empty CSP_HEADER, for instance) landed in the error log on every hit, and the health
service folded the same recommendations into a warning status that monitors alerted on. Both
were advisory information presented as trouble. Low risk: logging and one optional payload key.
Key Highlights
RecommendationLog: once per boot cache
Health: advisory stays advisory
Migration Notes
- No action required. The next boot after updating logs the current recommendations one
more time, then stays quiet until they change. Monitors that alerted on the
warningstatus for recommendation-only hosts go quiet.
composer update glueful/framework
v1.83.0 - Alnilam
Released: September 8, 2026
Minor: CSP_HEADER now does what its name says. The variable shipped in every
.env.example and was recommended at production boot, yet nothing in the framework read it.
From this release a non-empty value is sent verbatim as Content-Security-Policy on every
response that does not already carry a policy, and the new CSP_REPORT_ONLY=true switches it
to the report-only header. Moderate risk only for hosts that had already set the variable:
review the value before upgrading. Empty stays a no-op.
Key Highlights
One chokepoint, precedence to the response
CSP_REPORT_ONLY and an honest boot message
Migration Notes
- Empty
CSP_HEADER(the shipped default): no action. - Non-empty
CSP_HEADER: it will start being sent. Test it withCSP_REPORT_ONLY=truefirst; a policy written for a different app can block inline styles or third-party embeds. - Mirror
CSP_REPORT_ONLY=falseinto your.env.exampleif you keep one.
composer update glueful/framework
v1.82.3 - Alnasl
Released: September 7, 2026
Patch: the php -S … router.php quickstart serves deep links under a mounted SPA. With
public/admin/index.html present, PHP's built-in server resolved /admin/setup to that
directory index (SCRIPT_NAME=/admin/index.html, PATH_INFO=/setup), Symfony inferred
/admin as a base path and stripped it, and every admin deep link or reload 404'd locally —
while nginx and Apache served them. Low risk: local development only.
Key Highlights
router.php presents the front controller like a real web server
Migration Notes
- No action required. Restart any running
php -Saftercomposer update.
composer update glueful/framework
v1.82.2 - Alnasl
Released: September 7, 2026
Patch: a mounted SPA's index.html gets a document Content-Security-Policy, not the
static-asset one. SpaMountController applied SecurityHeaders::defaultStaticAssetHeaders()
— whose style-src 'self' forbids inline styles — to the HTML document as well. A built
front-end injects style elements at runtime, so the served app lost those styles: a primary
button with no background, in every environment. Low risk: behaviour-restoring.
Key Highlights
SecurityHeaders::defaultDocumentHeaders() and the csp mount option
Migration Notes
- No action required. If you had worked around the missing styles with a custom header in front of PHP, remove it; the framework now sends a correct document policy itself.
composer update glueful/framework
v1.82.1 - Alnasl
Released: September 7, 2026
Patch: boot-time re-pins reach the compiled container. A provider that re-binds a service
after the container is built ($this->app->load([...]) in boot()) used to guard on
instanceof Glueful\Container\Container, which the compiled container is not. With 1.82.0
making compilation succeed, such re-pins silently no-op'd in production and the service
reverted to the compiled binding. Low risk: behaviour-restoring.
Key Highlights
RebindableContainer
Migration Notes
- If a provider guards a boot-time
load()withinstanceof Glueful\Container\Container, change the guard toinstanceof Glueful\Container\RebindableContainer— otherwise the re-pin skips the compiled container in production. - Optional constructor dependencies (nullable or defaulted) absent from the container now
resolve to their default /
nullunder the compiled container, exactly as at runtime.
composer update glueful/framework
v1.82.0 - Alnasl
Released: September 7, 2026
Minor: the compiled container finally engages, and a never-installed production checkout
boots quietly. Every production boot used to log [Container][WARNING] container compilation failed and fall back to the runtime container — the framework's own core factories were all
"unsupported" by the compiler. Static factories now compile to direct calls, closure factories
and live objects such as the ApplicationContext are handed in after construction, and the
artifact lives under the app's storage/cache/container. Separately, a checkout that has not
been installed yet (no security keys) skips the boot-time security validation and resolves
extensions live once, writing the cache, instead of failing with "Extension cache missing".
Moderate risk: production runs a different (faster) container implementation from this
release on; installed hosts are otherwise unchanged.
Key Highlights
Compiled container, hydrated at boot
First run bootstraps itself
Migration Notes
- Compiled container now active in production. If something behaves differently only in
production, set
APP_DEBUG=trueto compare against the runtime container and report it. Delete<app>/storage/cache/container/to force a fresh compile. - Recompile a
container:compileartifact built before 1.82.0 once — it is still loaded but carries no runtime values. FORCE_HTTPSunset in production no longer draws a recommendation; unset means enabled.
composer update glueful/framework
v1.81.2 - Alnair
Released: September 7, 2026
Patch: the production command manifest is app-owned and validated. The cached console
command list lived in the framework package's own storage/cache, which never exists in a
dist install, so every host fell through to one shared /tmp/glueful_commands_manifest.php
and loaded it verbatim. A manifest written by an older framework on the same host fed phantom
command classes into every production boot: container compilation failed on the unknown class,
and resolving the tagged commands threw a 500 out of the console. Low risk: behaviour-restoring,
no API change.
Key Highlights
Manifest under the app, validated on load
Migration Notes
- No action required. On a host that showed
Cannot compile autowire definition for unknown class: …at boot, the next production boot after updating rewrites the manifest. Runningphp glueful commands:clearonce removes the old shared temp file explicitly.
composer update glueful/framework
v1.81.1 - Alnair
Released: September 7, 2026
Patch: providers loaded from the extension cache get register() called. discover()
used to construct the cached providers and return, so register() ran only on live
discovery — never in production, where the cache is mandatory. Console commands and runtime
bindings registered there silently vanished on every production boot. Low risk:
behaviour-restoring, no API change.
Key Highlights
register() runs on every boot
Migration Notes
- No action required. If an extension of yours registers commands or bindings in
register()and they were missing in production, they appear after this update.
composer update glueful/framework
v1.81.0 - Alnair
Released: September 6, 2026
Minor: the boot profiler dump is opt-in and best-effort. Every boot used to write a
hard-coded /tmp/boot_profile.log. On any host where a different OS user had created that
file first — a second site, or a CLI run as root followed by one as the site user — the
denied write was promoted to a fatal ErrorException by the framework's error handler, and
no command (including first-run provisioning) could boot. The dump is now enabled only by
BOOT_PROFILE_LOG, and a dump that cannot be written is skipped silently. Low risk: no
framework code read the file; minor only because a default changed and an env var is new.
Key Highlights
BOOT_PROFILE_LOG
Migration Notes
- No action required. If external tooling tailed
/tmp/boot_profile.log, setBOOT_PROFILE_LOG=/tmp/boot_profile.logto keep it.
composer update glueful/framework
v1.80.2 - Almach
Released: August 19, 2026
Patch: untouched migration sources classify pending, never divergent. A source with
zero receipts whose effects are absent or unverifiable is simply not migrated yet — the
healthy state of every disabled extension's schema on a fresh install. Previously it
classified Divergent, making migrate:verify exit non-zero on perfectly healthy installs
and breaking the documented migrate:run && migrate:verify upgrade chain for hosts
shipping disabled engines. Low risk: classification-only.
Key Highlights
AdoptionState::Pending
Migration Notes
- No action required. If your monitoring keyed on
migrate:verifyoutput, disabled engines now readpendinginstead ofdivergent.
composer update glueful/framework
v1.80.1 - Almach
Released: August 18, 2026
Patch: the protected migration lane can record its own operation on PostgreSQL.extension_operations.operation was created as string(16), but 1.80.0's
migrateProtected() writes protected_migrate (17 chars) — a hard 22001 truncation error
on PostgreSQL that SQLite-based tests never saw. The column is now 32 wide, with a width
tripwire test pinning every operation and status value against the declared DDL.
Migration Notes
- A database provisioned on exactly 1.80.0 reports the create migration Divergent (its checksum changed) — re-provision, or widen the column and update the recorded checksum by hand.
composer update glueful/framework
v1.80.0 - Almach
Released: August 18, 2026
Minor: schema custody closure — provision, protected providers, and host-enforced
manifests complete the schema-on-enable program. Installer provision now applies the app
path and every manifest core descriptor in one locked custody sequence; protected providers
get their own migration lane on the shared executor; and hosts can opt into refusing
undeclared package schema. Breaking for any host still leaning on 1.79's legacy seams
(none are known to exist): manifest declaration is unconditional, and the beta-era
legacy-alias receipt machinery (including migrate:normalize-receipts) is gone — no
supported installs carry pre-manifest ledgers.
Key Highlights
Provision is a complete locked pass
A migration lane for protected providers
Manifest declaration is unconditional
Migration Notes
- Declare every installed Glueful package's schema (descriptors or
"migrations": "none") before upgrading — an undeclared package's provider now throws at migration-path registration. First-party packages all declare as of this release. - If you used beta-era pre-manifest ledgers:
migrate:normalize-receiptsand thelegacyAliasesdescriptor field are removed. Re-provision, or rewrite ledgersourcevalues by hand before upgrading.
composer update glueful/framework
v1.79.1 - Alkaid
Released: August 18, 2026
Patch: tolerant index drops no longer poison the per-migration transaction.SchemaBuilder::dropIndex() has always swallowed a failed drop, but under v1.79.0's
per-migration transaction the errored statement aborted the whole transaction on
PostgreSQL (25P02) and failed every later statement — surfaced by fresh-chain migrations
that defensively drop-then-recreate an index. dropIndex now emits DROP INDEX IF EXISTS
on PostgreSQL and SQLite, so a missing index is a no-op instead of a transaction abort.
Schema-internal; no API, env, or config changes.
Migration Notes
composer update glueful/framework— nothing else.
composer update glueful/framework
v1.79.0 - Alkaid
Released: August 17, 2026
Minor: schema-on-enable — extension enablement becomes a migrate-first, lock-serialized
operation with a truthful record. Manifest migration descriptors
(extra.glueful.migrations) are now the sole schema inventory, and
extensions:enable/disable (CLI and HTTP alike) drive one bootstrap-ordered executor:
dependency dry-resolve, source-scoped locks, migrations first, checksum-verified readiness,
enabled state written last, terminal state persisted in a core-owned extension_operations
ledger. Moderate risk with one required upgrade step: run php glueful migrate:run
once after updating, before any extension enable — the executor refuses until the new core
operation ledger exists. Undeclared legacy packages keep booting and migrating globally,
but the new enable/readiness/adoption operations fail closed on them.
Key Highlights
Manifest migration descriptors as the single schema inventory
The enable executor and the operation ledger
Checksum-driven readiness, receipt normalization, and verifier-gated adoption
Migration Notes
- Required, once, before any extension enable: run the core migration that creates the
operation ledger — the executor refuses with
SchemaNotBootstrappedExceptionuntil it exists. - Package authors: declare
extra.glueful.migrations(or"none") in your manifest;extensions:enablenow refuses undeclared packages with the manifest remedy. Undeclared packages still boot and migrate via legacy globalmigrate:run. - Global runs are policy-scoped:
migrate:runskips disabledon_enabledescriptors and validates explicit file arguments against scope before any DDL.
composer update glueful/framework
php glueful migrate:run
v1.78.4 - Alioth
Released: August 17, 2026
Patch: the lazy-ledger contract completes v1.78.3. That release deferred database work
in the three migrate commands, but every extension provider still constructed
MigrationManager at boot via loadMigrationsFrom() — and its constructor connected and
ran version-table DDL, creating the migrations table as whatever role .env named. The
manager now resolves its connection on first database operation: only migrate() creates
the ledger, status and pending reads treat a missing ledger as zero applied migrations, and
rollback() reports nothing-to-rollback. Migration discovery and registration perform zero
database work, and read-only operational commands work with read-only credentials.
Migration-internal; no API, env, or config changes.
Migration Notes
composer update glueful/framework— nothing else.
composer update glueful/framework
v1.78.3 - Alioth
Released: August 16, 2026
Patch: the console works before the database does. migrate:run/rollback/status
resolved their migration manager — which connects and runs version-table DDL — at console
registration, so every glueful command required a reachable database just to list
commands: exactly the state a first-run provisioning flow exists to repair. Resolution now
happens on first use, pinned by a refusing-container regression test. Console-internal;
no API, env, or config changes.
Migration Notes
composer update glueful/framework— nothing else.
composer update glueful/framework
v1.78.2 - Alioth
Released: August 15, 2026
Patch: the Rector experiment concludes — value harvested, tool retired. Every parent-class method override in the framework now carries #[\Override], so signature drift against a parent fails at parse time, and the long-dead setAccessible(true) reflection calls (no-ops since PHP 8.1) are removed. Rector itself — the dev dependency, its config, and the composer scripts — is retired: its dry-run surface held zero bugs on an already-modern PHP 8.3 codebase whose correctness is enforced by PHPStan level 8 with no baseline and a 2,100+ test suite. Internal-only: no API, env, config, or behavioral changes for applications. Low risk.
Migration Notes
- Nothing to do:
composer update glueful/frameworkpicks up the patch; no application-facing changes. - Framework contributors:
composer rector/rector:fixno longer exist. For future PHP-version or PHPUnit major migrations, install Rector ad hoc — that episodic use is its sweet spot.
composer update glueful/framework
v1.78.1 - Alioth
Released: August 14, 2026
Patch: API documentation now generates with the route cache in place. A leftover storage/cache/routes_dev.php made generate:openapi abort with Route name '…' already exists — the generator's cache-detected reset replayed every route registration onto a router whose named-route registry boot had already populated. The reset is gone; generation relies on the manifest's idempotent load, and a cache-populated run now produces a byte-identical document to a cache-free one. Low risk: generation-only, runtime routing untouched.
Migration Notes
composer update glueful/framework— no config or code changes; the old "delete the route cache before generating" workaround is no longer needed.
composer update glueful/framework
v1.78.0 - Alioth
Released: August 12, 2026
Credentials in URL paths stop reaching the logs. Redaction has always been keyed on parameter names — query strings and body fields — but a secret carried in the path itself (signed payment links, magic links, one-time download URLs) was logged verbatim by the request logger at info level and by the exception handler at error level in every profile. Applications can now register credential-bearing route templates and have the secret segment masked in every framework log sink. Moderate risk: one new config key (logging.sensitive_paths) and env var (LOG_SENSITIVE_PATHS); with the default empty list, every path is logged byte-identically to 1.77.0.
Key Highlights
Configurable sensitive path redaction
Every framework path sink swept
Migration Notes
- No action required for apps without credential-bearing paths: the default pattern list is empty and log output is byte-identical.
- Apps issuing tokened URLs: register the templates —
'sensitive_paths' => ['/checkout/pay/{token}']— without any base-URL prefix. - Redaction covers framework log sinks only: reverse-proxy, web-server and CDN access logs still record the raw request line and remain the operator's responsibility.
- Exception messages that interpolate a URI are still logged verbatim — put the URI in the exception context (redacted), not the message (see
docs/SECURITY_NOTES.md).
composer update glueful/framework
v1.76.0 - Algol
Released: August 8, 2026
The complete database-layer roadmap in one release — the native alternative to Doctrine DBAL. Database failures are now typed (\PDOException-rooted hierarchy, so every existing catch keeps working), retries run on one honest, configurable budget shared between deadlocks and connection losses, SQLite alterations are fail-closed (six paths that silently did nothing now really execute via audited atomic rebuilds, or throw before mutation), and connections recover — provably-uncommitted transactions replay after reconnection, while commit-ambiguous losses are never replayed. Moderate risk: new env keys, three interface additions for external implementors, and SQLite migrations that previously "passed" by doing nothing now take effect or fail loudly.
Key Highlights
Typed database exceptions
SQLite alterations are fail-closed
Reconnect resilience
Migration Notes
- Applications:
composer update glueful/framework; optionally tuneDB_RETRY_MAX_ATTEMPTS/DB_RETRY_BACKOFF_MS. - Audit SQLite-targeting migrations that modify/drop columns or foreign keys: their intent now actually applies (or fails loudly) instead of silently passing.
- External implementors of framework interfaces:
TransactionManagerInterface::transaction()gained an optional?RetryBudgetparam;SchemaBuilderInterfacegainedexecuteSqliteRebuild()andexecuteSqliteNativeAlteration();TableBuilderInterfacegainedrename(). Connection::transaction()retry tuning moved to config —setMaxRetries()still governs directTransactionManageruse only.- Replay callbacks must build query chains inside the callback from the supplied connection; prebuilt builders retain the stale PDO.
- Code that retried on commit-phase
ConnectionLostExceptionwas risking duplicate commits — it now seesCommitOutcomeUnknownException(still aPDOExceptionsubclass); audit any such handler.
composer update glueful/framework
v1.75.0 - Algieba
Released: August 7, 2026
The whole framework now type-checks at PHPStan level 8 with zero suppressed errors. A 31-area campaign cleaned 914 errors of typing debt, raised the CI gate from level 6 to level 8 over src/ and config/, upgraded the engine to PHPStan 2.x, and finished by fixing all 111 baseline entries and deleting the baseline file. Along the way the sweep surfaced and fixed genuinely latent bugs — a reachable orHas() fatal, auth request attributes that were always null, an unreachable soft-delete branch. Moderate risk: the diff surface is wide, but every area landed behind the full test suite and the few contract-visible changes are listed in the migration notes.
Key Highlights
Level 8 everywhere, with no baseline
The sweep fixed real bugs, not just annotations
Honest contracts and hardened edges
PHPStan 2.x engine and advisory Rector
Migration Notes
- Applications:
composer update glueful/frameworkis enough — no new env vars, config keys, migrations, or default changes. - If you implement
WhereClauseInterface(rare): add theorWhereRaw()method. - If you subclass ORM relation classes: parents/related instances are typed
Model, notobject. - If you catch around
toJson(): unencodable payloads now throw a named error instead of returningfalse. - Installs with an empty query-cache
keyPrefixget the intended default prefix — the query cache re-keys once after upgrade (one round of cache misses, not an error). - Contributors / CI forks: the analysis gate is now level 8 with no baseline file.
composer update glueful/framework
v1.74.1 - Algenib
Released: July 30, 2026
Session enumeration no longer recurses into itself. Listing, counting, or bulk-managing a user's sessions through the container-resolved session store triggered an unbounded mutual recursion between SessionStore::listByUser() and the cache manager's findUserSessions() — each deferred to the other with no base case — and exhausted memory. The common login, logout, and refresh flows operate on a single session by token and were never affected, which is why it stayed latent. A pure bugfix, low risk.
Key Highlights
Cache-index enumeration is the manager's sole authority
Migration Notes
- Nothing to do: a pure bugfix with no API, config, or schema change. Any feature that lists or bulk-manages a user's sessions simply stops exhausting memory.
composer update glueful/framework
v1.74.0 - Algenib
Released: July 30, 2026
Username validation now matches the column, not a product rule. UsernameDTO and UserDTO accepted 3–30 characters, which quietly ruled out a whole category of application: one that uses a normalized email address as the username. Plenty of valid addresses exceed 30 characters. The framework now enforces only storage-safe invariants — required, trimmed, at least 3 characters, within the varchar(255) column, unique — and leaves narrower policies to the applications that actually know what their usernames are for. Strictly more permissive, no schema change, nothing previously valid becomes invalid.
Key Highlights
Storage-safe invariants in the framework, product rules in the app
Migration Notes
- Strictly more permissive: every username that validated before still validates. No migration — the column has always been
varchar(255). - If your application relied on the framework rejecting usernames longer than 30 characters, add that rule at your own input boundary; it is no longer enforced centrally.
composer update glueful/framework
v1.73.0 - Algedi
Released: July 29, 2026
Browsers get a first-class transport, and CSRF finally binds to the session. An opt-in HttpOnly cookie session now sits alongside the unchanged bearer path: one middleware adapts a cookie into the header auth already reads, one issuer owns every cookie attribute, and one login orchestrator means no transport can reach session issuance around the two-factor gate. Shipping alongside it is a security fix the transport depends on — CSRF tokens were binding to an IP + User-Agent fingerprint for every authenticated request, not to the session. The transport is off by default and bearer behavior is byte-identical, but the CSRF fix invalidates tokens held by authenticated callers at upgrade time. Read the migration notes before upgrading.
Key Highlights
Opt-in HttpOnly session cookies, without touching bearer auth
One login path, one two-factor gate
Session refresh and logout that never leak tokens
CSRF tokens bind to the session, not a fingerprint
Migration Notes
- CSRF tokens issued to authenticated callers before this release stop validating. There is no compatibility window and no automatic recovery: an affected client receives a
403and must fetch a new CSRF token or reload the page. Old fingerprint-keyed cache entries expire on their own. Unauthenticated forms are unaffected. - The browser session transport is opt-in and off by default. No action is required to keep bearer-only behavior; bearer extraction,
POST /auth/loginand its JSON response,/auth/refresh-tokenand/auth/logoutare all unchanged. - To enable it, set
SESSION_COOKIE_ENABLED=trueand addsession_cookiebeforeauthon the routes that should accept cookies (session_cookie:optionalfor pages that must survive a lapsed session). Seedocs/BROWSER_SESSIONS.md.
composer update glueful/framework
v1.72.1 - Alderamin
Released: July 26, 2026
Activation writes now recompile the extension cache from what was just written. Every activation surface runs a read→write→recompile sequence in one process: reading the enabled list primes the context config cache, ExtensionStateWriter mutates config/extensions.php, and the recompile previously resolved through the stale cache — persisting the PRE-write activation state. A just-enabled provider could be missing from the compiled cache; a just-disabled one could remain. Pure fix — upgrade and run.
Key Highlights
No-arg writeCacheNow() resolves from current file state
Migration Notes
- No new env vars, no migrations, no default changes, no API changes.
composer update glueful/framework
v1.72.0 - Alderamin
Released: July 26, 2026
Three additive extension seams: one provider order, one provider owner, one activation gatekeeper. A declarative cross-phase load-order contract shared by container compilation, discovery, cache generation, and cached boot; type-agnostic provider-to-package attribution so app-integrated provider packages keep honest managed_by; and a extensions.protected guard that makes generic enable/disable refuse providers owned by domain lifecycle flows. Hosts adopting none of the new contracts see byte-identical behavior — upgrade and run.
Key Highlights
One declarative provider order for every phase
Provider ownership survives any package type
Protected providers refuse generic toggles
Migration Notes
- No action needed: the new config key defaults to
[]and all three seams are inert until adopted. If you ship a lifecycle-managed extension (e.g. glueful/tenancy runtime enablement), declare it inextensions.protectedso generic toggles can no longer corrupt its state machine.
composer update glueful/framework
v1.71.3 - Alcor
Released: July 25, 2026
Console fix: extension-discovered commands no longer run in a parallel, never-booted world. Commands discovered from extensions (rather than registered as container services) were instantiated bare, which sent BaseCommand down its no-args path — a fresh ApplicationContext plus a fresh container in which extension boot() never ran. Those commands silently operated without capabilities, boot-registered contributors, or event listeners, so a CLI run could see (and write) different state than the running application. Pure fix — upgrade and run.
Key Highlights
Discovered commands receive the real booted container and context
Migration Notes
- No new env vars, no migrations, no default changes, no API changes. If you ship extension commands, they now observe the same booted state as HTTP requests — remove any workarounds that re-registered boot-time state inside command constructors.
composer update glueful/framework
v1.71.2 - Alcor
Released: July 22, 2026
Follow-up fix: non-pooled connection reuse is now scoped to framework-managed connections. 1.71.1's identity-keyed PDO reuse could collapse an intentionally independent, hand-built new Connection([...]) into the framework's shared session when their configs resolved identically (typical in CI) — turning session-level semantics (advisory locks, open transactions) into self-interactions and deadlocking race-style code. Reuse now requires the constructor's ApplicationContext; context-less constructions always get a fresh backend. The 1.71.1 leak fix is fully preserved. Pure fix — upgrade and run.
Key Highlights
Ad-hoc new Connection([...]) always gets its own backend again
Migration Notes
- No new env vars, no migrations, no default changes, no API changes. If you construct
Connectiondirectly and want the shared framework backend, pass theApplicationContextas the second constructor argument; without it you get an independent session.
composer update glueful/framework
v1.71.1 - Alcor
Released: July 22, 2026
Two runtime bugfixes: non-pooled connection reuse and OPcache-off route-cache warmup. Without pooling, Connection leaked a database backend per instance — enough short-lived containers exhausted the server's connection ceiling ("too many clients"). And route-cache warmup threw on every boot when OPcache was loaded but disabled. Pure fixes: no new env vars, no migrations, no default changes, no API changes.
Key Highlights
Non-pooled Connection no longer leaks a backend per instance
Route-cache warmup no longer throws when OPcache is loaded but disabled
Migration Notes
- No new env vars, no migrations, no default changes, no API changes. Both are internal runtime fixes; upgrade and run.
composer update glueful/framework
v1.71.0 - Alcor
Released: July 20, 2026
Outbound-webhook security & reliability seams: strict event dispatch, an SSRF-safe outbound-target resolver, and hardened API-key rotation. Three additive, application-agnostic building blocks extracted while hardening the commerce marketplace's seller webhooks. No new env vars, no migrations, no default changes. One behavioral note: API-key rotation no longer extends a predecessor's expiry (see Migration Notes).
Key Highlights
EventService::dispatchOrFail() — strict, at-least-once event dispatch
SafeOutboundTargetResolver — one SSRF-safe URL → validated, IP-pinned target
Hardened ApiKeyService::rotate()
Migration Notes
- API-key rotation no longer extends a predecessor's expiry. Before 1.71.0, rotating a key with a grace window could push a superseded key's
expires_atlater than its original value; it now takes the earlier of the two. If you relied on rotation to lengthen an old key's lifetime, issue a fresh key instead. Otherwise no action is required — the newnew_uuidfield is purely additive. - No new env vars, no migrations, no default changes. The event and HTTP additions are opt-in seams;
dispatch()and the existingsafeRequest*()SSRF behavior are byte-identical to 1.70.x.
composer update glueful/framework
v1.70.0 - Albireo
Released: July 16, 2026
A blob-policy composition seam plus two long-standing database fixes. Extensions can now contribute blob access policies simultaneously through BlobAccessPolicyRegistry; whereIn() works on update()/delete(); and createTable() plain indexes are no longer silently discarded on SQLite/PostgreSQL. Additive API, no new env vars, no migrations. One operational note for pre-existing SQLite/PostgreSQL dev databases (see Migration Notes).
Key Highlights
Blob access policy composition — BlobAccessPolicyRegistry + CompositeBlobAccessPolicy
whereIn() / whereNotIn() on write operations
createTable() plain indexes on SQLite/PostgreSQL
Migration Notes
- SQLite/PostgreSQL databases migrated before 1.70.0 are missing every plain index declared inline in a
createTable()callback — they were silently discarded. Fresh migrations are correct automatically; for existing databases, re-run the relevantCREATE INDEXstatements or re-migrate dev databases. Performance-only: data and query results were never affected. - No other action required — the registry seam is additive, and the
whereIn()write fix turns a previously throwing call into the behavior its builders already advertised.
composer update glueful/framework
v1.69.0 - Albali
Released: July 14, 2026
A boot-time config override seam: ApplicationContext::overrideConfig(), frozen once boot completes. One additive method that lets applications and extensions override configuration during boot. No new env vars, no migrations, no default changes; unbound behavior is byte-for-byte identical to 1.68.x. No action required.
Key Highlights
Process-local config overrides — ApplicationContext::overrideConfig()
Migration Notes
- No action required — the method is purely additive and nothing in the framework calls it. Existing apps behave identically.
- To adopt it, call
ApplicationContext::overrideConfig()from a service provider'sregister()(or any boot-phase code), before boot completes.
composer update glueful/framework
v1.68.0 - Ain
Released: July 10, 2026
Blob route extensibility: two generic, unbound-by-default seams over the blob endpoints, a reusable auth:optional mode, and a signed-URL fix for private uploads. No new env vars, no migrations, no default changes. The blob VIEW route's auth posture changes — but the controller remains the authoritative gate, so response shapes are identical. No action required.
Key Highlights
Per-action blob middleware — BlobRouteMiddlewareProvider
Application-chosen blob origins — BlobPublicUrlProvider
Optional route authentication — auth:optional
Fixed: signed URLs under globally private uploads
Migration Notes
- No action required. Both seams are unbound pass-throughs; the VIEW behavior change only adds a previously-broken capability (anonymous signed access in private mode) while preserving all existing responses.
- To adopt the seams, bind
BlobRouteMiddlewareProviderand/orBlobPublicUrlProviderin a service provider — the blob route registration andsignedUrl()soft-resolve them.
composer update glueful/framework
v1.67.0 - Adhil
Released: July 10, 2026
Four opt-in extension seams — independent DB sessions, around-execution wrappers, write-side row hooks, and blob lifecycle/authorization hooks. Every seam is an exact pass-through until your application binds it: no new env vars, no migrations, no default changes, and unbound behavior is byte-for-byte identical to 1.66.x. No action required — upgrade and adopt seams as needed.
Key Highlights
Independent database sessions — Connection::newPdo()
Around-execution wrappers — QueryExecutor::addExecutionWrapper()
Write-side row hooks — Connection::addInsertHook()
Blob lifecycle + authorization hooks
Migration Notes
- No action required. All four seams are unbound by default and exact pass-throughs; existing applications behave identically.
- To adopt a seam, bind your implementation in a service provider (e.g. bind
BlobCreatedHook/BlobAccessPolicyto your classes) — the framework'sUploadControllerfactory soft-resolves them. BlobRepository::forceDelete()permanently removes a blob row (bypasses soft-delete). Reach for it only in compensation paths; normal deletion remains the softstatus='deleted'flow.
composer update glueful/framework
v1.66.3 - Adhara
Released: July 6, 2026
Route caching no longer crashes routes whose where() constraint contains parentheses. After 1.66.2 re-enabled route caching for apps that mount an SPA, any dynamic route with a parenthesized constraint — e.g. a non-capturing (?:twig|css|js) group — raised ValueError: array_combine(): … must have the same number of elements on its first request. The compiled cache now stores each route's original path and constraints and rebuilds from them, instead of reverse-engineering the path from the regex. No action required — the cache format is bumped, so stale route caches regenerate automatically on upgrade.
Key Highlights
Lossless dynamic-route reconstruction from the compiled cache
Migration Notes
- No action required. The fix is transparent; the bumped cache-format version invalidates any pre-existing route cache so it rebuilds on the next boot. Running
php glueful route:cache:clear(orcache:clear) forces it immediately.
composer update glueful/framework
php glueful route:cache:clear
v1.66.2 - Adhara
Released: July 6, 2026
Mounting an admin/SPA no longer disables route caching. serveFrontend() registered the SPA mount root and /{rest} catch-all as closures, and RouteCache refuses to cache a route table containing any closure — so every SPA-mounting app ran uncached and logged a [RouteCache] Skipping cache … Convert to [Controller::class, "method"] syntax warning on each boot. The seam now uses controller handlers backed by a mount registry; asset/index serving is byte-for-byte identical. No signature or config change, no new env vars — affected apps regain route caching automatically after upgrading.
Key Highlights
Route caching restored for SPA-mounting apps
Migration Notes
- No action required. The
serveFrontend()signature and behaviour are unchanged; there are no new env vars and no config changes. After upgrading, apps that mount an SPA will build the route cache normally and the[RouteCache]boot warning disappears.
composer update glueful/framework
php glueful cache:clear
v1.66.1 - Adhara
Released: July 6, 2026
The extension installer is now synchronous. The 1.66.0 installer spawned composer require as a detached background job and made the client poll — but forking a long-lived PHP CLI from a web server (Apache/php-cgi/nginx+FPM) proved unreliable, and installs simply hung in queued. POST /extensions/install now runs composer inline and returns the result in one response; the extension installs disabled and is activated with the enable toggle (WordPress-style). Also fixes the catalog 422 that hid any extension with release history. The install API changed shape (single response, no job polling); run php glueful cache:clear after upgrading.
Key Highlights
Synchronous install — no queue, no polling
Type re-verification judges the latest release, not every one
Migration Notes
- The install API changed shape.
POST /extensions/installreturns the final result directly instead of a job id, andGET /extensions/install/{jobId}has been removed — await the single request. The 1.66.0 detached installer never worked under a web SAPI, so no functioning integration is affected. - Env (all optional):
EXTENSIONS_INSTALL_PHP_BINARY— absolute path to a CLI php used to run composer (leave blank to auto-detect; set it when the web SAPI's php isn't a usable CLI interpreter, e.g./usr/bin/phpbehind nginx+FPM).COMPOSER_BINARY— absolute composer path if it isn't on the webPATH.EXTENSIONS_INSTALL_AUTO_ENABLEhas been removed. - After upgrading, run
php glueful cache:clearso the corrected installable-extension catalog is rebuilt (the 1.66.0 catalog cache can hide affected packages until its TTL lapses).
composer update glueful/framework
php glueful cache:clear
v1.66.0 - Adhara
Released: July 5, 2026
Install extensions from the admin UI — no SSH required. A new install pipeline runs composer require for a catalog extension from the browser instead of the server terminal: the package is validated against the Packagist catalog, installed in a detached process that survives an FPM recycle, then auto-enabled in a fresh subprocess (to dodge the running worker's stale autoloader). Guarded by the system.config permission tier and a kill-switch that is off in production by default. Also fixes SVG uploads 400ing on the content check. Minor — three new optional EXTENSIONS_INSTALL_* env vars with safe defaults; no migrations, no breaking changes.
Key Highlights
Browser-driven extension install (composer require, detached)
Guardrails on the install path
SVG uploads no longer 400 on the content check
Migration Notes
- Nothing required to upgrade. The new
installblock inconfig/extensions.phpships with working defaults. - New optional env vars for the extension installer:
EXTENSIONS_INSTALL_ENABLED— master kill-switch; defaults on outside production, off in production.EXTENSIONS_INSTALL_AUTO_ENABLE(defaulttrue) — auto-enable right after a successful install.EXTENSIONS_INSTALL_TIMEOUT(default600) — seconds before acomposer requirerun is timed out.
- To use the installer in production, set
EXTENSIONS_INSTALL_ENABLED=trueand make the deploy'svendor/tree writable by the web user.
composer update glueful/framework
v1.65.3 - Acrux
Released: July 3, 2026
Random-string buffer overrun and static-asset MIME fixes. RandomStringGenerator::generate() could read past its random-byte buffer under unlucky rejection sampling — an intermittent "Uninitialized string offset" in anything generating passwords or tokens, and a quiet output-bias risk. Separately, static assets served through serveFrontend() were content-sniffed to text/plain, which the accompanying nosniff header turns into browsers refusing CSS and module scripts outright. Patch — bugfixes only, no new env, no migrations, no behavioral changes.
Key Highlights
RandomStringGenerator rejection sampling stays inside its buffer
serveFrontend() assets get extension-mapped MIME types
Migration Notes
- Nothing required. Pure bugfix patch — no new env, no migrations, no behavioral changes.
composer update glueful/framework
v1.65.2 - Acrux
Released: July 2, 2026
Array-valued field-selection params no longer 500. A public read/delivery endpoint that builds its FieldSelector from the request would return an unhandled 500 when a client sent fields/expand as an array (?fields[]=a), because Symfony's InputBag rejects non-scalar values. Field selection is a scalar syntax, so those params are now read tolerantly and an array value is treated as "no selection". Patch — bugfix only, no new env, no migrations, no behavioral changes.
Key Highlights
FieldSelector tolerates malformed array params
Migration Notes
- Nothing required. Pure bugfix patch — no new env, no migrations, no behavioral changes.
composer update glueful/framework
v1.65.1 - Acrux
Released: July 1, 2026
Extension-toggle and CLI hygiene fixes. php glueful extensions:enable/disable no longer leave a stray trailing-whitespace line in config/extensions.php (which tripped phpcs/CI on the very next lint), and four console commands that were unrunnable due to option-shortcut clashes with Symfony's globals now start cleanly. Patch — bugfixes only, no new env, no migrations, no behavioral changes.
Key Highlights
extensions:enable/disable write clean config
Console commands no longer clash with global shortcuts
Migration Notes
- Nothing required. Pure bugfix patch — no new env, no migrations, no behavioral changes. If you scripted
php glueful install --quietfor unattended installs, switch it to--unattended(the global-q/--quietnow resolves normally on that command).
composer update glueful/framework
v1.65.0 - Acrux
Released: June 30, 2026
Database, validation, and routing improvements. New QueryBuilder::forceDelete() (hard-delete on a soft-deletable table without dropping to raw SQL), validator coercion rules (CastToInt / CastToBoolean / CastToDate), a DbUnique exclude-by-column argument, an api_key_uuid request attribute for per-key attribution, and ServiceProvider::resetLoadedRoutes() for clean re-boots. Plus three routing/schema fixes — auth.user is always populated after auth, file-defined require_scope: params are now enforced, and alterTable()->dropColumn() actually drops. Minor — no new env, no migrations; scope enforcement is tightened (see Migration Notes).
Key Highlights
Database & validation toolbelt
Routing & schema correctness
Migration Notes
- Scope enforcement tightened. If you declared a route's scope as a middleware param —
->middleware('require_scope:read:content')— it was previously not enforced (it fell open) and now enforces fail-closed. Requests lacking the scope will correctly receive403. Routes using the#[RequireScope]attribute are unaffected. Everything else is additive — no new env, no migrations.
composer update glueful/framework
v1.64.0 - Zosma
Released: June 28, 2026
Configurable, auditable API keys — plus webhook and blob-visibility fixes. ApiKeyService now reads its brand prefix from config (API_KEY_PREFIX, default gf) so apps can rebrand generated keys, and its create/rotate/revoke paths emit framework entity events so key lifecycle is auditable (identity only, never the secret). Also fixes three latent webhook-management bugs and a blob-visibility bug where "public" uploads were stored private and 401'd on retrieval. Minor — one new optional env (API_KEY_PREFIX), backward compatible, no migrations.
Key Highlights
Rebrandable, auditable API keys
Webhook management + blob visibility fixes
Migration Notes
- Nothing required. Backward compatible:
API_KEY_PREFIXdefaults togf(reproduces existing keys), and no migrations ship. SetAPI_KEY_PREFIXonly if you want to rebrand keys. To audit key lifecycle, ensure an audit consumer is listening for theapi_keysentity events.
composer update glueful/framework
v1.63.5 - Yildun
Released: June 27, 2026
The webhook management API is now fully typed in OpenAPI. 1.63.4 added operation summaries to WebhookController; this fills in the schemas — query parameters, request bodies, and response shapes — so an application that mounts the controller gets a precise spec (and a typed client) for subscriptions and deliveries, not just path stubs. Patch — documentation metadata only (new doc-only DTOs + attributes), no behavioral change, no new env, no migrations.
Key Highlights
Typed query params, bodies, and responses for webhooks
Migration Notes
- Nothing required. Documentation metadata only. After
composer update, re-rungenerate:openapi(and your client codegen) to pick up the fully-typed webhook endpoints.
composer update glueful/framework
v1.63.4 - Yildun
Released: June 27, 2026
The webhook management API is now self-documenting. The framework ships a complete WebhookController (subscription + delivery management), but its methods carried no OpenAPI attributes — so an application that mounts these routes got working endpoints that were invisible to generate:openapi and the typed client. All 11 endpoints now carry #[ApiOperation]/#[ApiResponse]. Patch — documentation metadata only, no behavioral change, no new env, no migrations.
Key Highlights
WebhookController endpoints appear in generated docs
Migration Notes
- Nothing required. Documentation metadata only. After
composer update, re-rungenerate:openapi(and your client codegen) to surface the webhook endpoints in your spec.
composer update glueful/framework
v1.63.3 - Yildun
Released: June 26, 2026
Blob writes are now auditable. BlobRepository was constructed without an ApplicationContext, so its create/update/delete never dispatched entity events — blob uploads emitted no EntityCreatedEvent and silently couldn't be audited. It's now built with the context, so uploads emit events an audit/activity consumer can record. Bugfix patch — no new env, no migrations.
Migration Notes
- Nothing required. Bugfix only.
composer update glueful/framework
v1.63.2 - Yildun
Released: June 26, 2026
Image-variant caching fix. Serving a resized blob variant (GET /blobs/{uuid}?width=…) with the variant cache enabled returned a 500: UploadController cached the rendered image as raw bytes, which a JSON-based cache serializer (e.g. the Redis driver's SecureSerializer) can't encode — raw bytes aren't valid UTF-8 — so every cached resize threw Malformed UTF-8. The un-resized original was unaffected. Bugfix patch — no new env, no migrations.
Key Highlights
Resized image variants are cached correctly
Migration Notes
- Nothing required. Bugfix only; no env or config changes, no migrations.
composer update glueful/framework
v1.63.1 - Yildun
Released: June 25, 2026
Resilient event dispatch + dead auth events. Auth/security events (logins, logouts, failed logins, security violations) were silently not reaching their listeners: ActivityLoggingSubscriber — the first listener on every auth/security event — was unresolvable (it required a LogManager the container never registers), so it threw; and the dispatcher didn't isolate listener failures, so that one throw aborted the whole dispatch before any later listener ran. The session dispatcher swallowed the error, so logins succeeded with nothing logged. Bugfix patch — no new env, no migrations.
Key Highlights
A throwing listener no longer starves the rest of the chain
ActivityLoggingSubscriber is resolvable again
Failed logins now emit AuthenticationFailedEvent
Migration Notes
- Nothing required. Both are bugfixes; no env or config changes, no migrations.
composer update glueful/framework
v1.63.0 - Yildun
Released: June 25, 2026
Entity-deletion event + subclass domain-event dispatch. BaseRepository now emits an EntityDeletedEvent on a successful delete — completing the create/update/delete triplet so audit, cache-invalidation and notification consumers can react to deletes, not just writes. And the repository's event-dispatch helper is now protected, so repository subclasses (including those in extensions) can emit their own domain events through the same best-effort path. Additive — a new event (fires only if subscribed) plus a visibility widening; no env, no migrations.
Key Highlights
EntityDeletedEvent completes the entity CRUD event triplet
Repository subclasses can emit their own domain events
Migration Notes
- Nothing required. Both changes are additive; behavior is unchanged unless you subscribe to the new event or emit one from a subclass.
composer update glueful/framework
v1.62.0 - Xuange
Released: June 24, 2026
User-record enrichment seam. A new core contract lets an authorization extension attach fields — like a user's roles — to the records an identity store returns (/users, /users/{uuid}, /me), without the two extensions depending on each other. The read-side symmetric of the existing login-time identity.claims_provider seam. Additive — nothing changes unless an extension registers an enricher; no env, no migrations.
Key Highlights
UserRecordEnricherInterface + the users.record_enricher tag
Migration Notes
- Nothing required. The contract is additive; behavior is unchanged until an extension registers an enricher.
composer update glueful/framework
v1.61.2 - Wezen
Released: June 23, 2026
Permission gate fail-closed fix. Every #[RequiresPermission] / gate_permissions route returned 403 for fully authorized users — the auth.user principal the gate reads was never populated because AuthMiddleware's enricher lookup used a container id that never matched, so the enricher silently never ran. Routes guarded by attribute permissions (admin/RBAC/i18n endpoints) were unreachable. Bugfix patch — no new env, no migrations.
Key Highlights
#[RequiresPermission] routes no longer 403 authorized users
File / Memcached cache drivers accept colon-namespaced keys
Migration Notes
- Nothing required. Bugfix only.
composer update glueful/framework
v1.61.1 - Wezen
Released: June 22, 2026
CORS on every response. Cross-origin error and regular responses (422, 401, …) now carry Access-Control-Allow-Origin, so a separately-served frontend (e.g. a Vite dev SPA on another origin) can finally read their bodies. Previously only the OPTIONS preflight got CORS headers, leaving regular and error bodies blocked by the browser. Bugfix patch — no new env, no migrations, no action required.
Key Highlights
CORS headers on regular and error responses
Migration Notes
- Nothing required. Same-origin requests and disallowed origins are unchanged; allowed cross-origin requests now receive the CORS headers they should always have had on regular and error responses.
composer update glueful/framework
v1.61.0 - Wezen
Released: June 20, 2026
OpenAPI tag filtering. The doc generator can now drop operations from the generated spec by tag (documentation.options.tags.include / .exclude, env-driven), so a consumer-facing spec can hide infrastructure groups (Health, Documentation, Security) without turning off whole route sources. Additive and off by default (empty lists = no filtering) — no breaking changes, no migrations.
Key Highlights
Tag allow/deny for the OpenAPI spec
Doc-config cleanup
Migration Notes
- Nothing required. Filtering is off by default (both lists empty). To use it, set e.g.
API_DOCS_EXCLUDE_TAGS="Health,Documentation,Security"and regenerate the spec. - The removed
route_definitions/extension_definitionsconfig keys were already inert — safe to delete if you copied them into your app's config.
composer update glueful/framework
v1.60.0 - Vega
Released: June 19, 2026
Engine-agnostic installer + first-run setup seams. php glueful install now configures and migrates any database engine (MySQL/PostgreSQL/SQLite) — not just SQLite — and a new Glueful\Installer\ toolkit lets an app drive first-run setup from CLI or a UI without shelling out. Additive (no breaking API changes, no new env, no migrations) — but install is now interactive, so non-interactive callers should pass --quiet.
Key Highlights
install works with any database engine
Glueful\Installer\ seams (CLI or UI, no shelling out)
Safer .env + correct PostgreSQL DSN
Migration Notes
php glueful installis now interactive. It prompts for the database engine + credentials by default. Non-interactive callers (CI,post-create-project-cmd, scripts) should pass--quietto use the existing.envwithout prompts, or--skip-databaseto skip DB setup/migrations. The api-skeleton'spost-create-project-cmdis updated accordingly.- No env, config, or migration changes.
composer update glueful/framework
v1.59.0 - Unukalhai
Released: June 19, 2026
First-party frontend serving. A new ServiceProvider::serveFrontend() seam serves a built SPA or static bundle at any literal path (e.g. /admin) — with secure asset serving, an index.html deep-link fallback, and a content-hash-aware cache split. It replaces and removes mountStatic() (which only mounted at /extensions/{mount} and had no SPA fallback). One small migration if you used mountStatic(); everything else is additive.
Key Highlights
serveFrontend() — serve a SPA at any literal path
OpenAPI: less boilerplate per endpoint
HEAD requests to file responses no longer 500
Migration Notes
mountStatic()is removed. Replace$this->mountStatic('foo', $dir)(served at/extensions/foo) with$this->serveFrontend('/foo', $dir)(any literal path +index.htmlfallback). For a plain bundle that 404s on a miss, use$this->serveFrontend('/foo', $dir, ['spaFallback' => false]).serveFrontend()no-ops with a warning if the bundle has noindex.html(whenspaFallbackis on).- The unused
SpaManager/StaticFileDetector/SpaProviderare removed (dead code, no callers). No config, env, or migrations.
composer update glueful/framework
v1.58.1 - Thuban
Released: June 15, 2026
OpenAPI response-schema fidelity. Three additive reflect-generator fixes so typed ResponseData DTOs document response bodies accurately — the success envelope marks its keys required, and #[ArrayOf] now resolves array items in response mode. Fully additive: no behavior change for request DTOs, no config/env changes, nothing to migrate.
Key Highlights
#ArrayOf now works on response DTOs
Success envelope marks its keys required
Request-DTO safety preserved
Migration Notes
- Nothing to migrate. Fully additive — no behavior change for request DTOs, no config or env changes.
composer update glueful/framework
v1.58.0 - Thuban
Released: June 15, 2026
Typed request-DTO hydration v2. RequestData DTOs now handle arrays, nested DTOs, and path/query inputs — closing the v1 "flat-scalars, JSON-body-only" boundaries from 1.57.0. Fully additive: flat scalar v1 DTOs are byte-identical, there are no config or env changes, and nothing to migrate.
Key Highlights
Arrays & nested DTOs — no more TypeError sharp edge
Path & query sources via #FromRoute / #FromQuery
Cross-field validation & custom rules
Migration Notes
- Nothing to migrate. Fully additive — existing flat-scalar
RequestDataDTOs behave identically, and there are no config or env changes.
composer update glueful/framework
v1.57.0 - Sargas
Released: June 14, 2026
A types-first I/O convention and a single code-first OpenAPI generator. Controllers can now express request/response shapes as typed DTOs that drive both the runtime envelope and the generated spec; the OpenAPI generator is consolidated to the code-first reflect engine and the legacy docblock-parsing comments generator is removed. Mostly additive, but it ships as a minor for one breaking change. If you used the comments OpenAPI generator or documented routes with @route/@response docblocks, read the Migration Notes.
Key Highlights
Types-first request & response DTOs
One code-first OpenAPI generator
Reference adoption across core controllers
Migration Notes
- The comment-based OpenAPI generator has been removed;
reflectis now the only OpenAPI generator. documentation.generatorandAPI_DOCS_GENERATORare no longer supported — remove them from config/env (the value is ignored).- Route
@route,@summary,@requestBody,@response, and related docblock annotations are no longer read. - Document endpoints with typed DTOs plus
#[ApiOperation],#[QueryParam],#[ApiRequestBody], and#[ApiResponse]. See the OpenAPI reflect guide. - No migrations.
composer update glueful/framework
v1.56.0 - Rastaban
Released: June 13, 2026
The second wave of the June 2026 security & correctness hardening pass: queue/scheduler payload signing, SSRF-safe HTTP with validated-DNS pinning, unified sensitive-parameter redaction, fail-closed CORS/image defaults, and JWT temporal-claim enforcement. Almost entirely fixes, but several change defaults or add config/env vars (CORS credentials off by default; remote image fetch opt-in; queue/scheduler payloads signed by default; JWT requires exp) -- so it ships as a minor. Read the Migration Notes before upgrading.
Key Highlights
Queue & scheduler payloads are signed and gated
SSRF-safe HTTP + unified redaction
Fail-closed defaults + JWT temporal claims
Migration Notes
- CORS fails closed. The standalone handler no longer allows all origins by default, and
CORS_SUPPORTS_CREDENTIALSnow defaults tofalse. SetCORS_ALLOWED_ORIGINS(andCORS_SUPPORTS_CREDENTIALS=trueonly if you genuinely need credentialed cross-origin requests). - Remote image fetching is opt-in. With no
image.securityconfig, external image URLs are disabled and the allow-list is empty. Configureimage.security.allowed_domainsor install/configureglueful/media. - Queue & scheduler payloads are signed by default.
QUEUE_PAYLOAD_SIGNING/QUEUE_REQUIRE_SIGNED_PAYLOADSdefault on (inert withoutAPP_KEY). To drain legacy unsigned rows, temporarily setQUEUE_REQUIRE_SIGNED_PAYLOADS=false. Custom queue/scheduler handlers must implementJobInterface. - JWT requires
exp. Tokens withoutexp(or with expired/non-numericexp, futurenbf/iat) are rejected. - Memcached cache format changed. Flush the cache when upgrading a Memcached-backed deployment -- raw legacy string values that aren't valid serialized data now throw on read.
- Set
TRUSTED_PROXIESbehind a load balancer so client IPs resolve correctly. New optionalhttp.safe_fetch.max_redirects(default3). No migrations.
composer update glueful/framework
v1.55.0 - Peacock
Released: June 11, 2026
A security & correctness hardening release: a focused pass over routing/permissions, auth, storage paths, the database write-path, deserialization, and the container/extension boundary, from a five-part framework review. Mostly bug fixes, but several change behavior or defaults (permission attributes now enforce; API-key query param off by default; signed URLs fail closed without a secret; extensions fail loud at boot) and one adds a feature (range UPDATE/DELETE predicates) -- so it ships as a minor. Read the Migration Notes before upgrading.
Key Highlights
Route permission attributes now actually enforce
Auth & storage hardening
Database integrity + injection hardening
Container/extension boundary fails loud
Migration Notes
- Permission attributes now enforce. Routes using
#[RequiresPermission]/#[RequiresRole]without a permission provider bound will now 403. Bind a provider (e.g.glueful/aegis), grant the permissions, or remove the attribute from open routes. - API key query string is off by default. Move clients to the
X-API-Keyheader, or setsecurity.api_keys.allow_query_param = true. - Signed URLs require a secret. Configure
uploads.signed_urls.secret/SIGNED_URL_SECRET(orapp.key/APP_KEY) -- a distinct value per environment. Generation/validation throws otherwise. - Extensions fail loud at boot (non-prod). A previously-silent extension wiring failure will now surface; fix the binding (a bare interface id needs
['class' => Concrete::class]or a factory). - New optional config keys
security.api_keys.allow_query_param/security.csrf.rate_limit_fail_closed(both defaultfalse). No new env vars, no migrations.
composer update glueful/framework
v1.54.0 - Okab
Released: June 10, 2026
A coordinated release in three movements: a container-precedence fix that makes every "core default + extension override" seam genuinely overridable; the new Glueful\Entitlements core seam (contract-only — commercial capability gates for the forthcoming glueful/subscriptions); and a storage driver registry with the s3/gcs/azure factories extracted to first-party provider packs (breaking — lean core, same playbook as 1.52). glueful/storage-s3 ships alongside (covers R2/MinIO/Spaces/Wasabi via presets); gcs/azure packs follow shortly.
Key Highlights
Extension definitions now override core defaults (container precedence fix)
Entitlement seam (Glueful\Entitlements) — contract only
Storage driver registry + provider packs (breaking)
Migration Notes
- Cloud storage disks need their provider pack:
composer require glueful/storage-s3fors3disks (its presets cover R2, MinIO, Spaces, Wasabi).gcs/azureusers should hold the upgrade until those packs publish (following shortly).local/memory-only apps need nothing. - On deploy:
php glueful commands:cache(newstorage:testcommand) andphp glueful di:container:compile --force(the precedence fix only takes effect in a freshly compiled container). - Extension authors: your
services()definitions now genuinely override core defaults for the same id (previously dropped silently). Audit for unintentional core-id collisions. - Optional env:
UPLOADS_NATIVE_MAX_PRIVATE_TTL(default 900). No core migrations; no required env changes.
composer update glueful/framework
composer require glueful/storage-s3 # only if a disk uses driver: s3 / R2 / MinIO / Spaces / Wasabi
v1.53.0 - Nunki
Released: June 8, 2026
A backward-compatible release that adds two generic, chainable database extension seams — so extensions can enforce scopes, narrow queries, or veto statements without patching core — and folds in four bug fixes uncovered while building the upcoming glueful/tenancy extension. Both seams are no-ops on a plain install (zero behavior change). No env vars, no migrations, no breaking changes; composer update glueful/framework suffices.
Key Highlights
Chainable DB Extension Seams (interceptors + table hooks)
Four Bug Fixes (queue deserialization, write-path, container)
Migration Notes
- No action required.
composer update glueful/frameworkpicks up 1.53.0. No new env vars, no migrations, no API breaks; the seams are opt-in and inert unless an extension registers a hook. - The api-skeleton
^1.52.0constraint already permits 1.53.0 — no skeleton changes ship in this release.
composer update glueful/framework
v1.52.0 - Mizar
Released: June 7, 2026
A coordinated breaking release that makes core lean: four subsystems move out of the framework into standalone, opt-in glueful/* extensions, each behind a narrow seam core consumes only if bound. Archive → glueful/archive, CDN / edge-cache → glueful/cdn, queue operations (supervision / autoscaling / worker-metrics) → glueful/queue-ops, and rich media (image processing / thumbnails / metadata) → glueful/media. A plain core install boots, serves uploads, runs a lean single-worker queue:work, and caches responses with none of these subsystems' heavy dependencies present — intervention/image and james-heinrich/getid3 are removed from core. Every subsystem is restored with a single composer require. See the migration notes.
Key Highlights
Archive & CDN / Edge-Cache Extracted (seam-backed)
Queue Ops Extracted; Core Ships a Lean Worker
Rich Media Extracted; Uploads Stay in Core
Migration Notes
- Restore any subsystem with one
composer require(auto-discovered viaextra.glueful):glueful/archive,glueful/cdn,glueful/queue-ops,glueful/media. Runphp glueful migrate:runfor those that ship schema (archive). - Refresh the production command manifest on deploy. This release removes the core
archive:manage,cache:purge, andqueue:autoscalecommands; astorage/cache/glueful_commands_manifest.phpgenerated before the upgrade still references them and breaks CLI boot. Runphp glueful commands:cache --clear—php glueful cache:cleardoes not clear the command manifest. - No-extension behavior is graceful, not fatal. Seams degrade to no-ops/defaults:
NullEdgeCache(response caching still emits surrogate keys), leanqueue:work, type-only media metadata + original-served variants. Removed helpers/commands (image(),queue:autoscale, thequeue:worksub-actions) are absent (function/command-not-found), not error-printing stubs. - Namespace maps (when restoring an extension and updating app code):
Glueful\Services\ImageProcessor→Glueful\Extensions\Media\ImageProcessor;Glueful\Cache\EdgeCacheService→Glueful\Extensions\Cdn\EdgeCachePurger;Glueful\Queue\Monitoring\WorkerMonitor→Glueful\Extensions\QueueOps\Monitoring\WorkerMonitor;Glueful\Services\Archive\*→Glueful\Extensions\Archive\*. Full maps in the frameworkUPGRADE.md. - No new framework env vars, no core migrations. The api-skeleton is bumped to
^1.52.0and ships lean (extensions are opt-in; its publishedconfig/image.php,cache.edge,queue.workers.*ops blocks, andcapabilities.archivewere removed).
composer update glueful/framework
# then, to restore what you use:
composer require glueful/media glueful/queue-ops glueful/cdn glueful/archive
php glueful commands:cache --clear
v1.51.0 - Larawag
Released: June 6, 2026
A five-part refinement of the core notification subsystem. The framework now ships a real in-app database channel (the default ['database'] channel resolves end-to-end instead of failing as channel_not_found), validates channels at dispatch rather than construction, makes persistence optional and safe (NOTIFICATIONS_DATABASE_STORE=false), abstracts async queue dispatch behind an injectable seam, adds structured channel results (NotificationResult), and routes all channel registration through one extension boot() path. Mostly additive — but two deliberate breaking changes land in channel registration/dispatch. See the migration notes.
Key Highlights
Real database Channel + Dispatch-Time Validation
Optional, Safe Persistence + Injectable Async Queue
Structured Results + Extension-Driven Registration
Migration Notes
- Breaking:
ChannelManagerchannel-name methods renamed (no aliases). ReplacegetAvailableChannels()withgetRegisteredChannelNames(); for only the currently-available channels' names, use the newgetActiveChannelNames().getActiveChannels()(returning channel objects) is unchanged. - Breaking: notification jobs/commands require an
ApplicationContext.DispatchNotificationChannels,SendNotification,ProcessRetriesCommand, andNotificationRetryTaskresolve the shared container dispatcher and throwNotificationContextRequiredExceptionif constructed without a context — they no longer build ad-hoc managers or hardcode theEmailNotificationprovider. The queue worker and console kernel already provide a context. - Channel packages register from
boot(). Custom or not-yet-migrated channel extensions must register their channel/hooks via the newregisterNotificationChannel()/registerNotificationExtension()helpers; until they do, that channel won't auto-wire into the shared dispatcher used by the async jobs. - Retry config key moved from the
emailnotificationnamespace to channel-agnosticnotifications.retry(built-in defaults otherwise). - No new env vars, no migrations. The
notificationscapability default staystrue; setNOTIFICATIONS_DATABASE_STORE=falseto run without a database store.
composer update glueful/framework
v1.50.2 - Kochab
Released: June 5, 2026
Route docblocks can now document query parameters with an editor-clean @queryParam name:type="…" tag that the OpenAPI generator actually parses. The old approach overloaded the reserved @param tag (@param page query integer false "…"), which IDEs/Intelephense mis-read as undefined PHPDoc types (P1133 warnings). A latent doc-gen bug is also fixed: routes that declared a query parameter alongside a {id} path segment silently lost the path parameter from their spec. Framework-only — no env vars, no migrations, no API breaks.
Key Highlights
@queryParamroute-doc tag.CommentsDocGeneratorparses@queryParam name:type="description" [{required}]as anin: queryOpenAPI parameter — no more reserved-@paramfalse positives in your editor. The legacy positional@param … query …form still parses, so existing route docblocks are unaffected.- Path params no longer dropped. URL
{name}path parameters were auto-derived only when no parameters were documented at all; a route with a query param plus a{id}lost its path param from the generated spec. Path params are now always derived from the URL and merged with documented params (de-duplicated by name; an explicit docblock still wins). routes/resource.phpmigrated to@queryParamfor the/data/{table}list endpoint'spage/limit/sort/orderparams (they now actually appear in the spec).
Migration Notes
composer update glueful/framework is sufficient — the api-skeleton ^1.50.1 constraint already permits 1.50.2. No action required; the new tag is opt-in and the legacy @param form continues to work.
v1.50.1 - Kochab
Released: June 5, 2026
Two extension points that silently did nothing are now fixed. ServiceProvider::mergeConfig() delegated to a config.manager service that was never registered, so an extension's config/*.php defaults never reached config() — every first-party extension ran on empty/hardcoded fallbacks unless the app shipped its own copy. And LoginResponseBuildingEvent listeners' changes were discarded by the login-response shaper. Both now work as documented. Framework-only: no env vars, no migrations, no API breaks.
Key Highlights
mergeConfig()actually merges now. Backed by the newApplicationContext::mergeConfigDefaults(), extension config defaults are merged under framework/app/env config files (your app'sconfig/*.phpstill wins) and persist acrossclearConfigCache(). Affected extensions:glueful/aegis,conversa,email-notification,entrada,meilisearch,notiva,payvia,runiva.LoginResponseBuildingEventlisteners affect the response.LoginResponseShaper::shape()now reads$event->getResponse()back, so a listener can add fields (e.g. organization/department context) to the login response.
Migration Notes
composer update glueful/framework is sufficient — the api-skeleton ^1.50.0 constraint already permits 1.50.1. Behavioral note: enabled first-party extensions now receive their declared config defaults (previously ignored); review those defaults if you relied on the prior empty behavior.
v1.50.0 - Kochab
Released: June 4, 2026
The concrete user store is extracted to the first-party glueful/users extension, leaving a provider-agnostic core that talks to identity through UserProviderInterface + the canonical UserIdentity. In parallel, the framework now owns the database schema for its own subsystems — the auth security spine plus DB-backed platform capabilities (queue, scheduler, notifications, metrics, locks, uploads, archive) — as first-class, config-gated, source-tracked migrations, replacing lazy runtime DDL. Breaking (shipped as a minor per the pre-public policy): apps must enable a user store. See the migration notes.
Key Highlights
Provider-Agnostic Identity
Core Owns Its Schema
Ordered, Package-Scoped Migrations
Migration Notes
- Breaking: enable a user store. Core no longer ships
Glueful\Models\User/Glueful\Repository\UserRepository, andAuthenticatedUseris removed. Install and enableglueful/users(the api-skeleton does so by default). Without a store, auth fails closed. Seedocs/IDENTITY.md. api_keys.user_id→user_uuid. The column (andApiKeyServiceinput /ApiKeymodel field) is renamed; it remains an indexed UUID with no FK.- Schema is migration-owned. Run
php glueful migrate:run; capability tables install perconfig/capabilities.php+ driver config (queue.default,lock.default,uploads.enabled). Seedocs/MIGRATIONS_AND_CAPABILITIES.md.
composer require glueful/users
php glueful migrate:run
Older releases (v1.49.1 and earlier) live in the Release Archive. The version table at the top links every release; for the full machine-readable history see the CHANGELOG.