v1.52.0 — Mizar
[1.52.0] - 2026-06-07 — Mizar
Theme: Lean core — four subsystems extracted to optional extensions. A coordinated breaking release that moves Archive, CDN / edge-cache, queue operations (supervision / autoscaling / worker-metrics), and rich media (image processing / thumbnails / metadata) out of framework core into standalone
glueful/*extensions, each behind a narrow core seam core consumes only if bound. A plain core install boots, serves uploads, runs a lean single-workerqueue:work, and caches responses with zero of these subsystems' heavy dependencies present (nointervention/image,james-heinrich/getid3, and no GD/Imagick required). Every subsystem is restored with a singlecomposer require. Staying in 1.x per the pre-public breaking-changes policy — see Upgrade Notes andUPGRADE.mdfor full per-subsystem migration guidance.
Breaking Changes
- CDN / edge-cache subsystem extracted to the
glueful/cdnextension. Edge purging and edge cache-control headers now requirecomposer require glueful/cdn(auto-discovered viaextra.glueful). The duplicated edge/CDN code was removed from core:Glueful\Cache\EdgeCacheService(→Glueful\Extensions\Cdn\EdgeCachePurger, which now implements the retained core contractGlueful\Cache\Contracts\EdgeCacheInterface);Glueful\Cache\CDN\CDNAdapterInterfaceandGlueful\Cache\CDN\AbstractCDNAdapter(→Glueful\Extensions\Cdn\Adapters\*); thecache:purgeconsole command (Glueful\Console\Commands\Cache\PurgeCommand); and the deadGlueful\Helpers\CDNAdapterManagertrait. TheEdgeCacheServicecontainer binding was removed — core still bindsEdgeCacheInterfaceto the no-opGlueful\Cache\NullEdgeCache, so response caching keeps working (it still emits surrogate keys) and resolving the interface always succeeds. Thecache.edgeconfig block was removed; its settings move to the extension'scdnconfig key (theEDGE_CACHE_*env vars are now read only by the extension). Without the extension,php glueful cache:purgeis absent and edge purges/headers are silent no-ops. SeeUPGRADE.md. - Archive subsystem extracted to the
glueful/archiveextension. All archive code and schema were removed from core:src/Services/Archive(service,ArchiveServiceInterface,ArchiveHealthChecker, DTOs, andServiceProvider/ArchiveProvider), thearchive:manageconsole command (src/Console/Commands/Archive),migrations/archive,config/archive.php, and thearchivecapability (thecapabilities.archive/ARCHIVE_DATABASE_SCHEMAgate). TheArchiveProvideris no longer registered in the container. Apps that use archiving must nowcomposer require glueful/archive(auto-discovered viaextra.glueful) and migrate importsGlueful\Services\Archive\*→Glueful\Extensions\Archive\*. SeeUPGRADE.md. Intentional fix carried into the extension: a configuredarchive.storage.pathnow actually takes effect — under core, the deadarchive.config/storage_pathconfig keys plus a missingApplicationContextmeant the configured storage path was silently never applied. - Queue ops (supervised fleets / autoscaling / worker metrics) command surface extracted to the
glueful/queue-opsextension (part 1 of a staged breaking series — config relocates in a follow-up commit). Plainphp glueful queue:workis now a single lean worker: the oldqueue:worksub-actions (work(multi/manager mode),spawn,scale,status,stop,restart,health) and thequeue:autoscalecommand are removed/absent — invoking them is a generic command-not-found / unknown-argument error, with no stub printing an actionable message. The deleted core classes moved to the extension:Glueful\Queue\Monitoring\WorkerMonitor→Glueful\Extensions\QueueOps\Monitoring\WorkerMonitor;Glueful\Queue\Process\*(ProcessManager,ProcessFactory,WorkerProcess,AutoScaler,ScheduledScaler,ResourceMonitor,StreamingMonitor) →Glueful\Extensions\QueueOps\Process\*;Glueful\Console\Commands\Queue\AutoScaleCommand→ the extension. Core retains the lean worker plus theGlueful\Queue\Contracts\WorkerMonitorInterfaceseam bound by default to the no-opGlueful\Queue\Monitoring\NullWorkerMonitor, soqueue:workandQueueMaintenancekeep working on a plain checkout. Supervised fleets, autoscaling, and worker/job metrics now requirecomposer require glueful/queue-ops(auto-discovered viaextra.glueful), which restoresqueue:supervise(supervisor + leaf workers) andqueue:autoscale. Additive (already shipped this cycle, no action needed): newqueue:work --once/--connection=flags, andWorkerOptionsmax-jobs/max-runtimenow treat0as unlimited;ServeCommandstill shellsqueue:work --sleep=3(now one lean worker). Note: this is part 1 of a staged breaking series — the ops config keys (queue.workers.{process,auto_scaling,resource_limits,resource_thresholds,supervisor}and per-queueworkers/max_workers/auto_scale) relocate to the extension'squeue_ops.*in a follow-up commit. SeeUPGRADE.md. - Queue ops config relocated from core
config/queue.phpto theglueful/queue-opsextension (queue_ops.*) (part 2, final, of the staged breaking series — commands removed in part 1). The worker-management blocksqueue.workers.{process,auto_scaling,resource_limits,resource_thresholds,supervisor}and the per-queue ops keysqueue.workers.queues.<name>.{workers,max_workers,auto_scale}were removed from core and now live underqueue_ops.*in the extension (provided via the extension'sconfig/queue_ops.php+mergeConfig). Read remappings:config('queue.workers.process.*')→config('queue_ops.process.*'),…auto_scaling→queue_ops.auto_scaling,…resource_limits→queue_ops.resource_limits,…resource_thresholds→queue_ops.resource_thresholds,…supervisor→queue_ops.supervisor, andconfig('queue.workers.queues.<name>.workers|max_workers|auto_scale')→config('queue_ops.queues.<name>.*'). Stays in core: per-queuepriority/memory_limit/timeout/max_jobs,queue.workers.performance.*(read by the leanQueueWorker), andqueue.monitoring.*. The feeding env vars are unchanged (e.g.QUEUE_PROCESS_ENABLED,QUEUE_AUTO_SCALING,CRITICAL_QUEUE_WORKERS,QUEUE_MEMORY_WARNING) — they are simply read byglueful/queue-opsnow, so no.envchanges are required. SeeUPGRADE.md. - Rich media (image processing, thumbnail generation, media metadata) extracted to the
glueful/mediaextension. The two heavy depsintervention/imageandjames-heinrich/getid3were removed from core and now ship with the extension. The moved classes (namespace map):Glueful\Services\ImageProcessor→Glueful\Extensions\Media\ImageProcessor;Glueful\Services\ImageProcessorInterface→Glueful\Extensions\Media\Contracts\ImageProcessorInterface;Glueful\Uploader\ThumbnailGenerator→Glueful\Extensions\Media\ThumbnailGenerator;Glueful\Uploader\MediaMetadataExtractor→Glueful\Extensions\Media\MediaMetadataExtractor.Glueful\Uploader\MediaMetadatais unchanged and stays in core. The globalimage()helper is now extension-provided — on a plain core install it is undefined (function-not-found, not a stub).FileUploader::getThumbnailGenerator()/getMetadataExtractor()were removed.IMAGE_*env vars andconfig/image.phpare now extension-owned; theUPLOADS_THUMBNAILS/UPLOADS_IMAGE_PROCESSING/THUMBNAIL_*config keys stay in core (config/uploads.php/config/filesystem.php) but are inert (media-gated no-ops) untilglueful/mediais installed. Without the extension:uploadMedia()returnsthumb_url: nullplus a type-onlyMediaMetadata, and the blob-resize endpoint serves the original image (returning415only when an explicit format conversion is requested). Restore full rich-media support withcomposer require glueful/media(auto-discovered viaextra.glueful). SeeUPGRADE.md.
Upgrade Notes
- Restore any extracted subsystem with one
composer require(each auto-discovers viaextra.glueful); enable it in the app'sconfig/extensions.phpif your app gates extensions there:composer require glueful/archive— archiving + thearchive:managecommand + theARCHIVE_DATABASE_SCHEMAgate (runphp glueful migrate:run).composer require glueful/cdn— edge purging + cache-control headers +cache:purge; move anycache.edgeoverrides to the extension'scdnconfig.composer require glueful/queue-ops—queue:supervise(supervisor + leaf workers) +queue:autoscale+ worker/job metrics; thequeue.workers.*ops blocks move toqueue_ops.*(same env vars, no.envchanges).composer require glueful/media— image processing / thumbnails / metadata + theimage()helper; republishesconfig/image.php.
- 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 --clearas part of the deploy —php glueful cache:cleardoes not clear the command manifest. (SeeUPGRADE.md→ Command cache.) - No-extension behavior is graceful, not fatal (the seams are bound to no-op/defaults): response caching still emits surrogate keys (
NullEdgeCache);queue:workruns as one lean worker;uploadMedia()returnsthumb_url: null+ type-onlyMediaMetadataand the blob-resize endpoint serves the original (415 only on explicit format conversion); archiving is simply unavailable. The removedimage()helper andqueue:autoscale/queue:worksub-actions are absent (function/command-not-found), not error-printing stubs. - Queue ops is a two-stage breaking move (within this release): the commands/classes and the
queue.workers.*ops config both relocate toglueful/queue-ops. Core keeps per-queuepriority/memory_limit/timeout/max_jobs,queue.workers.performance.*, andqueue.monitoring.*. The additivequeue:work --once/--connection=flags andWorkerOptions0 = unlimitedship in core regardless. - No new framework env vars; no core migrations. The four extensions own their own schema/config. Full namespace maps and per-subsystem steps are in
UPGRADE.md.