Package Architecture Transition
Why The Current Root-Managed Model Is Problematic
WebBlocks CMS currently ships as a root-managed Laravel application where CMS core files live directly in the installation root alongside user-owned application files. That model makes upgrades fragile because CMS product code and install-specific project code share the same top-level filesystem.
When CMS updates are applied by replacing or copying root-managed files, removed upstream core files are not guaranteed to disappear from downstream installs. A stale removed core file can remain in the install root, still be autoloaded or rendered by Laravel, and silently override newer shipped behavior. This is exactly the class of problem recently confirmed by a stale root Blade file in a downstream install.
The current architecture also keeps CMS updates tightly coupled to Git state and root-wide file synchronization. That makes it harder to reason about ownership boundaries, harder to preserve install-specific customization safely, and harder to make updates predictable across existing installs.
Target Direction
The target architecture is a Composer-managed Laravel package:
- Package name:
fklavyenet/webblocks-cms - Installed path:
vendor/fklavyenet/webblocks-cms - Canonical installed package source of truth:
vendor/fklavyenet/webblocks-cms
In the target model, CMS core code is installed and updated as a normal Composer package instead of being copied into the user-owned Laravel project root.
This means:
- CMS PHP source belongs under package
src/ - Laravel package resources stay in package-level
config/,database/,resources/,routes/,public/, andstubs/ src/is not where every package file should go- the user-owned Laravel root should own
app/,config/,database/,public/site/,resources/,routes/,storage/, andcomposer.json
System Update must align with this Composer package layout. In installed package-native consumers, the updater applies package-rooted release artifacts to vendor/fklavyenet/webblocks-cms; it must not keep packages/webblocks-cms as a second active, updated runtime copy. A packages/webblocks-cms tree belongs to source-maintained development checkouts or legacy transition leftovers only.
When a legacy Composer vendor install is repo-shaped, System Update normalizes vendor/fklavyenet/webblocks-cms to the flat package root. After normalization, src/, docs/, routes/, resources/, database/, public/, config/, and stubs/ live directly under vendor/fklavyenet/webblocks-cms; repo-root leftovers such as artisan, app/, bootstrap/, packages/, plugins/, and tests/ are removed from the package root replacement.
project/ may remain temporarily as a compatibility layer during the transition, but it should not remain the long-term required customization model for install-specific behavior.
The expected starter-project direction is a separate Laravel starter such as fklavyenet/webblocks-cms-starter, where the user-owned project root composes the CMS package instead of embedding all CMS core files directly.
Current v1.32.8 Consumer Readiness
Consumer package readiness has now started, but it is intentionally partial and explicit:
- fresh Laravel consumers can install the package and run
webblocks:install - the package uses a focused fresh-install migration path for clean consumer installs instead of replaying the full historical root migration chain
- maintenance-repo package migrations remain guard-disabled and inert by default
App\Models\Userremains the temporary consumer auth boundary inv1.32.8- the package installer patches
App\Models\Userautomatically with a package trait and writes a timestamped backup first - package-owned login, logout, install notice, admin protection, public home, views, and assets are now sufficient for the first clean consumer path
- this is still not a separate starter repository, and it does not yet remove the app-owned
Userboundary
Current Root App Cleanup State
The real Composer consumer app tree can be minimal while CMS runtime loads from vendor/fklavyenet/webblocks-cms. The maintenance repo now mirrors that boundary more closely: root app/ no longer keeps package-counterpart wrappers by default.
Removed wrapper categories:
- package-counterpart console commands, except the host-owned
ProjectInitCommand - CMS admin/public controllers and package-counterpart middleware whose routes now point at package classes, except the maintenance shell's install redirect middleware
- package-counterpart admin/public form requests
- package-counterpart mailables
- package-counterpart CMS models
- package-counterpart support classes across blocks, media, pages, sites, system, updates, search, visitors, and operational transfer/promotion domains
Intentionally still root-owned or deferred:
app/Models/User.php, baseController.php, and service providers remain host-owned Laravel shell files.- auth/profile/install files, including the install redirect middleware, remain host-owned until the starter/install boundary is deliberately redesigned.
- auth, profile, install, and project-layer remain host or transition boundaries.
- legacy asset shims
Asset,AssetFolder,BlockAsset, andApp\Support\Assets\...have been removed; package media models and support classes are now the authoritative runtime and test surface. App\Support\WebBlockshas been removed; root config, views, and tests now useWebBlocks\Cms\Support\WebBlocksas the product identity/version source.- empty package-counterpart root
app/directories are removed rather than kept as transition markers. - root migrations, config overrides, runtime
public/cms, root Blade compatibility wrappers, and root seeder wrappers remain outside this cleanup.
The cleanup improves package transition and starter readiness because the maintenance repo now tests the same minimal app assumption as a fresh package consumer. It still does not make the repo fully starter-ready: install/auth, User, root migration authority, root update/install operational authority, and root runtime asset compatibility paths remain final blockers.
Target Update Architecture
The long-term update flow should be Composer/package-managed and Git-agnostic.
The target update architecture is:
- no root-wide CMS core file copying
- CMS core installed and updated through Composer packages
- controlled runtime upgrade steps after package update, including migrations
- cache clear where needed
- explicit catalog repair as a separate operator maintenance workflow when needed
- controlled asset publish or sync only when actually required
This keeps install-owned root files separate from package-owned CMS core files and prevents removed CMS core files from lingering indefinitely in downstream installs simply because they once existed in the root.
Asset Build Boundary
The Composer package and maintenance repository are static-asset consumers, not frontend build-chain hosts. WebBlocks CMS must not ship or require Vite, the Laravel Vite plugin, Tailwind, npm, Node, package lockfiles, public/build, public/hot, or @vite runtime hooks for CMS-owned assets.
CMS-owned assets belong in root public/cms for the maintenance runtime and package packages/webblocks-cms/public/cms for release artifacts. WebBlocks UI remains an upstream UI project consumed through pinned published assets, and WebBlocks UI Manager remains the first-party operator plugin for release/CDN publishing workflows. Do not move WebBlocks UI source compilation, npm build scripts, dist generation, or hot-file assumptions into CMS core or its release package.
Ownership Boundaries
Target package-owned CMS paths:
packages/webblocks-cms/src/during the in-repo transition phase- later
vendor/fklavyenet/webblocks-cms/src/in installed environments - package
config/ - package
database/ - package
resources/ - package
routes/ - package
public/ - package
stubs/
Target user-owned project-root paths:
app/config/database/public/site/resources/routes/storage/composer.json
This split keeps Laravel application ownership with the install while CMS product ownership moves into the package.
Host Product Coexistence Boundary
Package-first CMS installs must preserve host application boundaries when CMS is installed beside another Laravel product. CMS should avoid route, config, view, and table collisions with the host app, and it must not assume that the host app's /admin route belongs to CMS.
The canonical CMS admin prefix is /webadmin, with a configurable prefix still the target direction for future coexistence flexibility. Host-owned login and CMS-owned authorization decisions are documented in Coexistence. CMS static assets remain under public/cms and are served from /cms/....
When package-owned CMS auth routes are active, /webadmin/login is part of the package boundary. Its Blade surface must stay under the webblocks-cms:: view namespace, use the WebBlocks UI guest auth shell, load the pinned WebBlocks UI CSS/JS plus /cms/css/guest.css, and resolve product brand/logo assets from /cms/brand. CMS product brand assets must provide normal, dark-surface, on-accent/inverse, and high-contrast favicon/browser-tab variants so auth and product shell contrast is solved with explicit assets instead of CSS filters.
Admin route prefixes must not reuse physical public asset directory segments. The retired /cms admin prefix collided with the active public/cms asset directory because Nginx try_files can resolve /cms/ as a directory before Laravel receives the route. Current package architecture therefore keeps /webadmin/... for CMS admin and package login routes, reserves /cms/... for static assets only, and forbids CMS-owned /cms aliases, /cms redirects, and restored CMS-owned /admin routes. The old public/cms/index.php handoff is not part of the package boundary and must remain absent from both root and package public assets.
Migration Phases
Phase 0: Document And Scaffold
Introduce the package architecture plan and create an in-repo package skeleton without moving runtime code yet. Root app behavior remains unchanged.
Phase 1: Minimal Package Bootstrap
Add the package service provider and local path Composer wiring so the package exists as a real installable unit inside the repository. Keep boot logic intentionally minimal and avoid changing runtime behavior.
Phase 2A: Bootstrap Contract
Refine the package service provider so it defines the bootstrap contract for future package-owned resources without making those resources authoritative yet.
In this phase, the provider may safely prepare guarded loading and publish registration for package config/, routes/, resources/views/, database/migrations/, public/, and stubs/, but only when real package files exist.
Current root runtime behavior still remains unchanged because the package skeleton only contains placeholders. Until runtime files are actually moved into the package in later phases, the root Laravel application remains the authoritative source for active CMS routes, views, config, migrations, and public assets.
The first package-owned default config path has now started with package config/webblocks-updates.php. During the transition, that package file provides CMS-owned defaults while the existing root config/webblocks-updates.php remains in place as the install-level override and backward-compatible application config file.
Config Classification
Current root config/ files fall into two transition groups.
CMS product default candidates:
webblocks-cms.phpcms.phpcontact.phpdemo_media.phpwebblocks-updates.php
Laravel app-owned or install-owned config that should stay root-owned:
app.phpauth.phpcache.phpdatabase.phpfilesystems.phplogging.phpmail.phpqueue.phpservices.phpsession.php
The current low-risk transition rule is to move CMS-owned default config only when it preserves stable product behavior and clear install override semantics. The package-owned default set now includes webblocks-cms.php, cms.php, contact.php, demo_media.php, and webblocks-updates.php. The root config files for existing CMS behavior remain in place during the transition as install-level overrides and backward-compatible application config entry points. webblocks-cms.php is package-only for now and owns transition controls: diagnostics routes, public status routes, admin status routes, and package migration loading stay disabled by default, while package admin route loading is enabled so package-owned admin routes can become authoritative.
Phase 2: Move Clearly Package-Owned Source
Begin moving CMS-owned PHP source into package src/ in small reviewable slices, updating namespaces and service provider bootstrapping only as each moved area is ready.
Package console bootstrap is now also proven through the read-only diagnostic command webblocks:package-status. That command is package-owned, registered only in console contexts, and reports package bootstrap presence without changing files, database state, cache, config, or update state.
The first PHP source move should follow equally conservative criteria: CMS-owned, small, easy to reason about, no database or Eloquent dependency, no controller or request dependency, and narrow reference updates. The first moved class is SearchTextNormalizer, a pure search-text helper now owned by package src/Support/Search/.
Current Search support boundary:
- package-owned now:
SearchTextNormalizer,PublicSearchRebuildResult,PublicSearchIndexer,PublicSearchQuery,PublicSearchSchema,SearchablePageResolver,BlockSearchTextExtractorRegistry, andReindexesPublicSearch - no Search support class currently needs to remain root-owned for project-specific reasons; the root
App\Support\Search\ReindexesPublicSearchshim has been removed
Current non-Search Support audit boundary:
- no additional non-Search Support helper was moved in this audit step because none of the reviewed candidates met the current low-risk package-owned criteria
MediaKindResolveris small and deterministic, but it currently depends onApp\Models\Mediaconstants and is referenced from a controller path, so it is not yet independent enough for this phaseDatabaseExecutionStrategyResolverremains root-owned for now because it directly affects database dump or restore execution strategy, environment inspection, and backup or restore runtime safetySiteHandleremains root-owned for now because it is used by models, requests, and site transfer or clone flows, so moving it now would cross routing, portability, and persistence-adjacent boundaries too earlySiteDomainNormalizerremains root-owned for now because it is still used by models, requests, route resolution, and migrations, confirming the earlier risk assessment
Contact support boundary:
- package-owned now:
ContactMessageNotificationResult - root-owned for now:
ContactMessageNotifier, because it still owns mail transport calls, contact model interaction, and config-based recipient resolution ContactMessageNotificationResultwas safe to move because it is a tiny immutable result object with no model, DB, request, config, mail, migration, or serialized payload coupling and only a narrow notifier reference update
Block type support boundary:
- package-owned now:
BlockTypeContract - root-owned for now:
BlockTypeContractRegistry, because it still depends on block models, catalog sync definitions, translation registry behavior, resource-path inspection, and the root-owned audit or admin flows that consume those resolved contracts BlockTypeContractwas safe to move because it is a small contract DTO with constructor-only state plus deterministic array serialization and no model, DB, request, config, command-side-effect, migration, or serialized payload coupling
Page layout markup boundary:
- root-owned for now:
LayoutMarkup LayoutMarkupwas not moved in this step because, although it is stateless and small, it is used directly by page-layout form requests, page layout manager logic, public slot wrapper resolution, and an admin Blade form; moving it now would cross request-validation and public-rendering boundaries inside the broader Pages or PublicRendering area that is still intentionally root-owned
Formatting support boundary:
- package-owned now:
InlineRichTextRenderer - root-owned for now:
SafeRichTextRenderer, because it still owns the richer HTML sanitization contract, allowed-tag behavior, DOM parsing rules, and public rich-text rendering semantics InlineRichTextRendererwas safe to move because it is a small deterministic formatter with no model, DB, request, config, migration, or serialized payload coupling and only a narrow Blade plus unit-test reference update
Support source migration map:
- Search: package-owned for current runtime support, including the reindex trait used by package models. Root
App\Support\Search\...shims should not be restored. - Formatting: candidate after dependency isolation.
InlineRichTextRendereris now package-owned as the low-risk formatting helper, whileSafeRichTextRendererremains root-owned because it defines the higher-risk sanitization behavior. - BlockTypes: candidate after dependency isolation.
BlockTypeContractis a small value object, but the namespace is anchored byBlockTypeContractRegistry, admin routes, and a root console audit command. - BlockTypes: candidate after dependency isolation.
BlockTypeContractis now package-owned as a narrow value-object move, but the namespace is still anchored byBlockTypeContractRegistry, admin routes, and a root console audit command. - Media and Assets: package-owned media models and support classes are authoritative for the removed legacy asset shims. Remaining media work should avoid restoring root
Asset,AssetFolder,BlockAsset, orApp\Support\Assets\...wrappers. - Pages and PublicRendering: root-owned until a dedicated migration phase. These classes control route resolution, layout selection, page assets, slot wrappers, public presenters, page duplication or import, and public rendering behavior with model and request coupling throughout.
- Pages and PublicRendering: root-owned until a dedicated migration phase.
LayoutMarkupwas reviewed as a possible exception, but it remains root-owned because it still sits directly on page-layout requests, slot-wrapper resolution, and admin-view rendering even though its own logic is stateless. - Blocks: root-owned until a dedicated migration phase. This area owns block payload writes, translation persistence, block deletion, catalog sync, trusted HTML extraction, and request-scoped public registries that sit directly on block persistence and renderer contracts.
- SharedSlots and Revisions: root-owned until a dedicated migration phase. These classes depend on block trees, revision tables, schema checks, translation rows, and restore or snapshot semantics.
- Sites, Sites\\ExportImport, and SitePromotion: root-owned until a dedicated migration phase. These areas are tightly coupled to models, routing, portability, archives, serialized transfer payloads, clone or delete flows, promotion safety backups, and public-site resolution.
- System and System\\Updates: root-owned until a dedicated migration phase. These classes own settings persistence, installed-version state, backup or restore, SQL validation, update download or extract flow, and database execution strategy.
- Install and ProjectLayer: do not move yet. These classes touch installer flow,
.envwrites, route or provider loading, install-state checks, and project-root customization boundaries. - Navigation, Locales, Users, Visitors, Contact, and Icons: candidate after dependency isolation. Each group contains some smaller helpers or result objects, but current implementations still rely on models, auth, mail, schema inspection, HTTP fetches, or settings-backed runtime behavior.
- Navigation, Locales, Users, Visitors, Contact, and Icons: candidate after dependency isolation.
ContactMessageNotificationResultis now package-owned as a narrow value-object move, while the remaining groups still rely on models, auth, mail, schema inspection, HTTP fetches, or settings-backed runtime behavior. - Admin, Audit, and Database: candidate after dependency isolation.
AdminPagination,CurrentActorResolver, andDestructiveDatabaseCommandGuardare small, but each still hangs off root settings, auth, or application safety hooks. - WebBlocks: package-owned
WebBlocks\Cms\Support\WebBlocksis now the product identity and version source for both package consumers and the maintenance repo root.
Phase 2 source checkpoint note:
- the initial low-risk helper and value-object moves completed successfully through
v1.31.60 - the local package-wired development environment was updated successfully after
v1.31.60, confirming the checkpoint remains compatible with the maintained local workflow - opportunistic low-risk PHP source moves are now intentionally paused
- do not continue moving runtime-heavy classes without a dedicated focused phase plan and dependency audit
Current blockers for higher-risk groups:
- direct
App\Models\...or Eloquent query coupling across Search, Pages, Blocks, Sites, Navigation, Locales, Icons, Visitors, and System - request, route, controller, or view coupling in Admin, Pages, PublicRendering, Formatting, and some BlockTypes helpers
- schema, migration-shape, or table-existence checks in Search, SharedSlots, Revisions, Visitors, Install, and System
- config, env, HTTP, mail, filesystem, process, backup, update, and local runtime coupling in Contact, Icons, Install, System, and Updates
- serialized archive or transfer payload coupling in Sites\\ExportImport, SitePromotion, Page import, and legacy asset compatibility helpers
Phase 3: Move Package Resources
Move clearly package-owned config, routes, views, migrations, seeders, public assets, and stubs into package-level Laravel resource folders. Introduce package load and publish behavior incrementally instead of all at once.
The current Phase 3 seeder slice now covers the package-owned catalog seeder boundary plus its package-owned aggregator:
- package-owned now:
CoreCatalogSeeder,IconCatalogSeeder,PageTypeSeeder,LayoutTypeSeeder,SlotTypeSeederunderpackages/webblocks-cms/database/seeders/ - root compatibility entrypoints remain in
database/seeders/so existing installs, tests, and current runtime or update entrypoints can keep callingDatabase\Seeders\... - the package-owned
CoreCatalogSeederremains only an ownership move: it still delegates to root-ownedPageLayoutSeederandBlockTypeSeeder, and current rootDatabaseSeederplus update entrypoints still call the root compatibility wrapper - still root-owned for now:
PageLayoutSeeder,BlockTypeSeeder,DatabaseSeeder, and active System Update post-install commands - package seeder ownership in this phase is about namespace and boundary migration only, not about changing current root update authority
Next Phase: Package Resource Boundary
The next transition focus after v1.31.60 is package resource ownership, not more opportunistic helper moves.
v1.31.62 Package Resource Boundary Pilot
The v1.31.62 checkpoint turns the package resource boundary into a more explicit and testable pilot without transferring active runtime ownership yet.
- package
routes/,resources/views/,database/migrations/,public/, andstubs/now exist as explicit reserved package boundary directories with marker files that document future ownership intent - package config defaults remain CMS-owned under package
config/ - matching root config files remain the install-level override layer and backward-compatible application config entry points
- the package service provider keeps package publishing explicit and package-tagged, but publishing remains inert unless a developer intentionally runs
vendor:publish - the package view namespace
webblocks-cmsis now registered as a safe package boundary pilot without changing current root admin or public view resolution - package routes, package views, package migrations, package public assets, and package stubs are still not active authoritative runtime ownership in this phase
webblocks:package-statusnow reports reserved-versus-populated package resource readiness in a strictly read-only way
This pilot does not move active root routes, root views, root migrations, root public assets, controllers, requests, models, services, or System Update behavior.
v1.31.63 Package View Namespace Activation Pilot
The v1.31.63 checkpoint turns the previously reserved package view namespace into a concrete, testable package-owned diagnostic boundary without changing active runtime ownership.
- package
resources/views/diagnostics/package-status.blade.phpnow exists as a real package-owned internal diagnostic Blade view - the diagnostic view is rendered only through the
webblocks-cms::namespace and is not exposed through any admin or public route webblocks:package-statuscan now optionally run--view-checkto render that diagnostic view in a strictly read-only way and confirm the package view namespace resolves correctly- default
webblocks:package-statusoutput remains lightweight and read-only, while the optional view check still performs no file writes, cache writes, config writes, database writes, or install-state changes - active root admin and public views remain authoritative, and no existing root view path or runtime route ownership changes in this phase
This pilot proves package view namespace loading with a real package-owned Blade file while intentionally avoiding any move of active root admin or public views.
v1.31.64 Package Route Boundary Pilot
The v1.31.64 checkpoint turns the previously reserved package routes boundary into a concrete, testable diagnostic route pilot without changing active route ownership.
- package
routes/diagnostics.phpnow exists as a real package-owned diagnostic route file for future package-internal diagnostics - the package service provider keeps package diagnostic route loading explicitly guarded behind
webblocks-cms.diagnostics.load_routes, so package diagnostic routes are not loaded into normal runtime by default webblocks:package-statusnow reports package route boundary presence, package route file status, expected diagnostic route file existence, guarded route-loading state, and whether the diagnostic route is currently loaded- active root admin and public routes remain authoritative, and no existing root admin or public route files were moved or changed in this phase
This pilot proves the package route boundary with a real package-owned diagnostic route file while intentionally avoiding any migration of active admin or public route ownership.
v1.31.65 Package Boundary Completion
The v1.31.65 checkpoint completes the remaining non-runtime package boundary pilots for migrations, public assets, stubs, and the Composer-managed update-flow target without moving active runtime ownership.
- package
database/migrations/,public/, andstubs/now keep clearer reserved-boundary marker documentation for their future package-owned roles - package migration loading is now explicitly guard-disabled through
webblocks-cms.boundaries.load_migrations, so package migrations remain inert unless a later focused runtime phase intentionally wires them - package public asset and stub publishing remain explicit and package-tagged; they now publish the first package-owned asset marker and starter stubs without replacing root runtime assets or the current installer
webblocks:package-statusnow reports migration boundary status, public asset boundary status, stub boundary status, the Composer-managed update target note, and the continued rule that root runtime remains authoritative- current root Composer behavior, root runtime loading, and System Update behavior remain unchanged in this checkpoint
This checkpoint completes the package boundary pilot phase. The repository now has concrete, testable package boundaries for routes, views, migrations, public assets, stubs, and Composer-managed update intent while active runtime ownership still remains in the root application.
Next Phase: First Real Package-Owned Runtime Slice
- choose one narrow runtime slice that is clearly package-owned and low-risk enough to move end to end
- move only when route, view, migration, asset, or runtime ownership rules are explicit for that slice
- verify backward compatibility and install expectations before any active runtime authority shifts from root to package
- keep System Update behavior unchanged until a later dedicated update-flow phase intentionally redesigns it
v1.32.0 Runtime Migration Phases 1-2
The v1.32.0 release is the first real package-owned runtime slice checkpoint. It begins package-owned runtime work with three deliberately small guarded slices that prove package runtime ownership without displacing the current CMS runtime.
Phase 1: guarded package diagnostics runtime slice
- package
routes/diagnostics.phpnow points at a package-owned controller underpackages/webblocks-cms/src/Http/Controllers/Diagnostics/PackageDiagnosticsController.php - that controller renders the existing package diagnostic view
webblocks-cms::diagnostics.package-status - the diagnostics route still stays off by default behind
webblocks-cms.diagnostics.load_routes - this is intentionally a reserved internal package path only and does not replace any root admin or public runtime route
Phase 2A: first focused package admin slice
- package
routes/admin.phporiginally introduced one small package-owned admin runtime status slice:admin.webblocks-cms.runtime-status, now mounted at/webadmin/_webblocks-cms/runtime-status - that status route uses a package-owned controller and package-owned Blade view under
packages/webblocks-cms/resources/views/admin/runtime-status.blade.php - package admin route loading is now enabled by default and the active CMS admin route tree now loads from package
routes/admin.php - the reserved admin status route itself stays off by default behind
webblocks-cms.admin.load_status_route - package admin routes keep the normal install, auth, admin-access, and super-admin system-access middleware requirements where appropriate
- active admin runtime ownership is now package-owned for Pages, Blocks, Media, Shared Slots, Navigation, Block Types, Page Layouts, Sites, Site Domains, Site Variables, and Locales, while Users, System, install/update, backup/restore, export/import, promotion, auth/profile, migrations, and root runtime assets remain root-owned
Phase 2B: first focused package public slice
- package
routes/public.phporiginally introduced one small package-owned public runtime status slice:webblocks-cms.public.runtime-statusat/_webblocks-cms/runtime-status - that route uses a package-owned controller and package-owned Blade view under
packages/webblocks-cms/resources/views/public/runtime-status.blade.php - package public route loading is now enabled by default and the active CMS public route tree now loads from package
routes/public.php - package-owned public entry controllers now handle home, localized home, search, localized search, search JSON, page show, localized page show, contact message submit, privacy-consent sync, and the
admin-api.*internal domain endpoints - package-owned public entry views now cover the page and search entry templates through
webblocks-cms::public.pages.showandwebblocks-cms::public.search.show - the reserved package public status route itself stays off by default behind
webblocks-cms.public.load_status_route - public asset runtime authority and install/update boundaries still remain root-owned outside the explicitly moved package-owned public route, model, support, and view slices
Why these slices stay partially guarded
- root runtime remains authoritative for installs outside intentionally moved package-owned slices
- the reserved package paths avoid route-name and path conflicts with existing admin and public runtime
- the separately guarded status routes let package bootstrap, route loading, view loading, middleware behavior, and status reporting be tested without forcing those reserved diagnostics paths into normal runtime
- the moved runtime authority is still intentionally partial, so high-risk groups such as models, most admin implementation classes, broader support layers, migrations, assets, and System Update behavior avoid premature package ownership
Next Possible Route Phase
- continue shrinking root route compatibility loading only after the remaining admin and public implementations behind the package route files are moved or intentionally left root-owned
- keep reserved diagnostics and runtime-status routes explicitly guarded even while normal CMS admin and public route trees are package-authoritative
- preserve route names, paths, middleware, and redirect behavior while package route authority stays ahead of deeper runtime extraction
- treat future route cleanup as a compatibility-reduction phase, not as proof that the CMS is already consumer-package ready
Next Possible View Phase
- move real package-owned views only in focused follow-up phases grouped by runtime concern, for example package-owned diagnostics first, then carefully audited admin or public view ownership later
- keep route ownership and view ownership aligned so a future moved view is introduced only when the owning runtime path is intentionally package-managed
- preserve clear install override and root-authority rules until each route or view ownership phase is explicitly designed and verified
Package Config Defaults Vs Root Install Overrides
- Package
config/should continue to define CMS-owned default values. - Root
config/remains the install-owned override layer during the transition. - A package config file should not become authoritative for runtime behavior until the override story and bootstrap wiring are explicit and stable.
Package Migration Loading And Publishing Strategy
- Package migrations should stay non-authoritative until real package-owned migrations exist and their ownership is intentionally moved.
- When migration ownership begins, prefer package loading for CMS-owned migration files and explicit publish guidance only where install-local customization is truly needed.
- Do not mix migration-boundary work with unrelated runtime refactors.
- Root
database/migrations/remains the compatibility and authority layer for source-maintained installs. The source-maintained update path requires the maintenance-repository root Composer autoload signal forWebBlocks\\Cms\\ => packages/webblocks-cms/src/; a consumer install having apackages/webblocks-cmsdirectory is not enough. Package consumer updates must use explicit package-owned update migrations and must not implicitly run host Laravel application migrations. - Package consumer fresh installs use the package-owned
database/migrations/freshschema throughwebblocks:install. The installer preflights partial CMS tables before that schema runs, stops with diagnostics by default, and only renames empty partial tables when the operator provides--repair-partial. PageLayoutSeederandBlockTypeSeederremain root-owned for now because they still cross page-layout catalog, block-type sync, and broader Pages or Blocks runtime boundaries.DatabaseSeederalso remains root-owned as the active install entrypoint and installed-version writer.
Package Route Ownership Strategy
- Package route ownership is now active for the CMS admin and public runtime trees through package
routes/admin.phpandroutes/public.php. - Root
routes/web.phpis now reduced to install, auth, profile, and compatibility loading of those package-owned CMS route files. - Route moves must continue preserving middleware, bindings, names, paths, modal flows, redirects, and downstream install expectations.
- The diagnostic, admin runtime-status, and public runtime-status routes remain separately guarded reserved paths and are not part of the normal always-on CMS route surface.
- Route authority does not yet imply full package runtime ownership because many handlers behind those routes still depend on root models, support code, views, and assets.
Package View And Resource Ownership Strategy
- Package
resources/viewsnow owns the diagnostic view, the guarded admin and public runtime-status views, the icon catalog admin views, the public layout shell, the public page and search shells, the public search modal, and the package-owned slot entry views. - Root
resources/viewsnow keeps compatibility wrappers for moved public layout, page, slot, and search entry views, while still remaining authoritative for most admin screens and for the broader public block-renderer compatibility tree that has not yet been fully extracted. - View moves should stay aligned with the owning runtime path so package route authority does not drift too far ahead of the actual owning view and controller layer.
- Root views remain the compatibility path for the majority of active CMS rendering outside the intentionally moved
webblocks-cms::surfaces.
Package Public Asset Publish Or Sync Strategy
- Package
public/should eventually own CMS-owned publishable assets. - Transition work should distinguish CMS-owned package assets from install-owned
public/site/...overrides. - Asset publishing or sync should happen only when real package assets exist and the update flow clearly defines when publishing is required.
- Current publish intent remains package-tagged and explicit.
public/cms/package-boundary.jsonis the first package-owned publishable asset and can be published throughwebblocks-cms-assets. - Package
public/cms/now also carries the public layout CSS and JS used by the moved package-owned public layout, but current rootpublic/cms/...asset URLs still remain authoritative in active runtime for compatibility while install-ownedpublic/site/...assets remain authoritative for per-site overrides. - Package
public/cms/must not containindex.php; CMS admin entry is/webadmin, not a front-controller bridge from the static asset directory. - WebBlocks UI CDN pinning and the default icon manifest sync source remain unchanged in this phase.
Package Stubs Strategy
- Package
stubs/should be reserved for reusable generated-file templates that belong to CMS product behavior. - Install-specific or project-specific scaffolding should not move into CMS package stubs by default.
- Starter-oriented stubs now live under package
stubs/starter/, but current installer behavior and root project scaffolding remain authoritative until a dedicated starter package intentionally adopts them.
Package Publish Tag Intent
webblocks-cms-configis reserved for publishing package-owned CMS default config files into the install root when a developer intentionally needs that workflow.webblocks-cms-assetspublishes package-owned CMS public assets into the active runtime compatibility path atpublic/cms.webblocks-cms-stubspublishes package-owned starter stubs.- These tags do not change runtime behavior on their own and remain inert until
vendor:publishis explicitly run.
Composer-Managed Update Flow And Post-Update Commands
- The long-term target remains Composer-managed package updates followed by controlled runtime steps.
- Expected post-update steps may later include migrations, block type sync, cache clear, or asset publish or sync, but only when those package-owned resources become real and intentionally wired.
- The canonical release artifact is now the package root itself, not the maintenance repository root. Update ZIPs are valid when the archive root, or one top-level wrapper directory, contains the package
composer.json,src/,config/,resources/,database/,routes/, andpublic/layout expected byfklavyenet/webblocks-cms. - The old root-managed updater archive shape is intentionally retired for modern package-native updates. It remains valid only as an explicit bridge artifact for pre-package-native installs such as
1.31.53, whose updater cannot validate package-rooted ZIPs yet. - Package-rooted release metadata must require a bridge-capable updater (
minimum_client_versionof1.32.18or newer). Older installs should receive the compatible bridge first, then use the modern package-rooted artifact after the bridge has installed package-native validation and apply code. - During the current transition, the root Laravel application remains install-owned and continues to run maintenance mode, migrations, seeders, sync commands, cache clears, and installed-version persistence from the install root.
- In-app updates now apply the validated package artifact into
packages/webblocks-cms/and, when Composer autoload shows that the active consumer runtime still loadsWebBlocks\Cms\fromvendor/fklavyenet/webblocks-cms/..., the matching safe vendor package runtime root. They do not overwrite the install-owned root shell, root config overrides, root migrations,project/,storage/,.env, orpublic/site/. - Root-managed bridge archives are not a relaxation of modern validation. A bridge archive must keep the old
artisanplus rootcomposer.jsonshape solely for legacy client compatibility and must install updater code that can then enforce the strict package-rootedfklavyenet/webblocks-cmsshape. - The
v1.31.65boundary-completion checkpoint keeps this as a target note only. Current root Composer behavior and runtime update flow still remain authoritative until the first real package-owned runtime slice exists.
Target install flow once the package-starter split is ready:
composer require fklavyenet/webblocks-cms- install-level Laravel root remains responsible for
.env, rootcomposer.json,storage/, install-owned config overrides, and any install-specificproject/customizations that still exist during the transition - package discovery should load
WebBlocks\Cms\WebBlocksCmsServiceProvider - package diagnostics such as
webblocks:package-statusshould confirm package readiness without mutating state
Target update flow once Composer-managed package updates become authoritative:
composer update fklavyenet/webblocks-cms- run migrations
- clear caches where needed
- publish or sync package assets only when real package assets require it
- run package diagnostics such as
webblocks:package-status - synchronize installed-version state only when the update corresponds to a real release boundary
- run explicit catalog repair separately when shipped catalog rows need maintenance
Current compatibility rule:
- today, those install and update flow notes are target-state documentation only
- current root Composer behavior, installer behavior, and in-app System Update behavior remain authoritative until a later dedicated update-flow phase intentionally changes them
Future Starter Project Split Direction
- The long-term direction remains a separate starter project that depends on
fklavyenet/webblocks-cmsas a package. - The current in-repo package exists to establish boundaries and ownership before that split is attempted.
- The starter split should happen only after the remaining root boundaries are redesigned: install/auth/profile runtime, the app-owned
Usermodel, root migration authority, root update/install operational authority, and the active rootpublic/cmsruntime asset path.
Next Step After Reserved Boundaries
- Move one resource type at a time from reserved boundary to active package ownership.
- Start only when the exact runtime-loading rule, install override story, and publish/update behavior are clear for that resource type.
- Prefer focused phase plans such as package views, package migrations, or package public assets rather than mixing multiple runtime resource types into one checkpoint.
- Keep runtime-heavy source moves behind dedicated dependency audits instead of folding them into resource-boundary pilot work.
Phase 4: Package-Managed Update Flow
Shift update behavior toward Composer-managed CMS package updates plus controlled post-update steps such as migrations, cache clear, and asset publish or sync when needed. Catalog repair remains an explicit operator maintenance workflow instead of a default update step.
The current readiness checkpoint now includes:
- package Composer autoload for
WebBlocks\Cms\Database\Seeders\ - retained root path-repository development wiring to
packages/webblocks-cms - explicit documentation that current root System Update behavior remains authoritative until a later dedicated update-flow phase intentionally changes it
Phase 5: Starter Project Split
Introduce the separate starter-project direction, such as fklavyenet/webblocks-cms-starter, so new installs start from a user-owned Laravel root that depends on the CMS package instead of cloning the CMS core repository into the project root.
The current checkpoint adds only boundary-readiness groundwork for that future split:
- more CMS-owned seeders now live under the package instead of the root app namespace
- more low-risk runtime support helpers now live under package
src/Support/ - root
app/compatibility wrappers are no longer kept by default; package-counterpart PHP wrappers have been removed while root Blade, seeder, and runtime asset compatibility paths remain where still needed - package composer metadata, provider discovery, path-repository development wiring, and documented target
composer requireorcomposer updateflow now form the starter-foundation readiness baseline
Existing-Install Migration Guidance
Existing installs will need a conservative migration path:
- keep current installs working while the package transition is incomplete
- avoid large one-step moves that mix runtime refactors with packaging changes
- preserve install-specific root files as user-owned project state
- stop relying on root-wide CMS core file replacement as the update mechanism
- introduce clear guidance for removing obsolete root-managed CMS core files once their package-owned replacements exist
The transition should prioritize low-risk incremental movement over a single rewrite.
Current Status
Package transition consolidation is complete for all safely movable CMS-owned source in this repository.
- Package-owned authority now covers the safely movable CMS route, view, model, seeder, shared-partial, admin-layout, and supporting runtime source domains.
- Package-counterpart root
App\...classes have been removed from the maintenance repo app tree; root Blade files, root seeders, and rootpublic/cms/...runtime copies remain intentionally in place as compatibility wrappers or compatibility paths. - Active runtime asset URLs still use root
public/cms/...compatibility paths even where matching package-owned source files exist underpackages/webblocks-cms/public/cms/.... - The remaining final boundaries are install/auth/profile runtime, the app-owned
Usermodel, root migration authority, root update/install operational authority, and the future starter split design. - Because of those blockers, the package is not yet ready for starter split even though the safe CMS-owned source consolidation work is complete.
This repository change is only the first low-risk transition step:
- it adds architecture documentation
- it creates the in-repo package skeleton at
packages/webblocks-cms/ - it adds a minimal package
composer.json - it adds a
WebBlocks\Cms\WebBlocksCmsServiceProvider - it wires the root project to path-require the package locally
The provider now defines the package bootstrap contract for future package resources, but those package resources are not yet authoritative because the current CMS runtime files still live in the root application.
The v1.31.62 pilot makes those package resource boundaries more concrete by adding explicit reserved boundary marker files under package routes/, resources/views/, database/migrations/, public/, and stubs/. These directories now exist as documented package-owned targets for later phases, but their contents still remain non-authoritative placeholders in this checkpoint.
The v1.31.63 pilot advances only the package view namespace boundary by adding one real internal diagnostic Blade view under package resources/views/diagnostics/package-status.blade.php and an optional read-only webblocks:package-status --view-check render probe. This proves package namespace-based view loading with a concrete package-owned view while leaving active root admin and public view resolution authoritative.
The v1.31.64 pilot advances only the package route boundary by adding one real package diagnostic route file under package routes/diagnostics.php, while keeping route loading explicitly guarded off in normal runtime. This proves package route-file ownership boundaries without moving any active root admin or public routes.
The v1.31.65 checkpoint completes the remaining inert boundary pilots by keeping package migrations explicitly guard-disabled, confirming package public asset and stub publishing remain inert until real package-owned files exist, and documenting Composer-managed package updates as the target boundary without changing the current root update flow.
The v1.32.0 release starts that planned move with guarded runtime migration phases 1-2:
- the package diagnostics runtime slice is real and package-owned end to end through a package controller plus the existing package diagnostic view, but it remains guard-disabled by default
- one focused admin runtime slice is now package-owned end to end through package
routes/admin.php,src/Http/Controllers/Admin/PackageAdminStatusController.php, andresources/views/admin/runtime-status.blade.php, but it remains guard-disabled by default on a reserved path - one focused public runtime slice is now package-owned end to end through package
routes/public.php,src/Http/Controllers/Public/PackagePublicStatusController.php, andresources/views/public/runtime-status.blade.php, but it remains guard-disabled by default on a reserved path webblocks:package-statusnow reports the diagnostics runtime slice, package admin slice, package public slice, and the explicit route guards in a still read-only way- root routes and root views remain authoritative for the existing CMS runtime outside these reserved package-only guarded paths
- package
config/webblocks-cms.phpnow owns explicit transition config values: diagnostics, public status routes, admin status routes, and package migration loading stay disabled by default, while package admin route loading is enabled for active package-owned admin route authority
The following historical checkpoint notes describe how package authority was introduced. Where they mention root App\... wrappers, the current broad root app cleanup supersedes that state: package-counterpart PHP wrappers are now intentionally absent unless listed in the current root app cleanup state above.
The current Step 1 runtime-authority checkpoint extends that boundary further:
- active CMS admin routes now load from package
routes/admin.php, with rootroutes/web.phpreduced to install, auth, profile, and compatibility loading - active CMS public routes now load from package
routes/public.php, including home, localized home, search, localized search, search JSON, page show, localized page show, contact submissions, privacy-consent sync, andadmin-api.* - package-owned public controllers now back that public entry slice under
packages/webblocks-cms/src/Http/Controllers/Public/ - package-owned
ContactMessageRequestand package-owned public entry views now back the moved public route entrypoints - root
App\Http\Controllers\PageController,PublicSearchController,ContactMessageController,PublicPrivacyConsentController, andApp\Http\Requests\ContactMessageRequestwere later removed as redundant package-counterpart wrappers - root models and support classes remain only where they serve host-owned or explicit transition domains; Users, install/profile/auth, root public/admin asset runtime paths, migrations, and System Update behavior remain boundaries, so the package is still not ready to serve as a fully independent starter runtime without deeper extraction
The current Step 2 public-rendering checkpoint extends package authority further behind those already-package-owned public routes:
- package
resources/views/layouts/public.blade.phpnow owns the active public layout shell under thewebblocks-cms::namespace - package
resources/views/pages/show.blade.php,resources/views/search/show.blade.php,resources/views/search/partials/modal.blade.php, and packagepages/partials/slot*.blade.phpnow own the active public page shell, public search shell, public search modal, and slot-entry rendering layer - root
resources/views/layouts/public.blade.php,resources/views/pages/show.blade.php,resources/views/search/show.blade.php,resources/views/search/partials/modal.blade.php,resources/views/pages/partials/slot.blade.php, andresources/views/pages/partials/block.blade.phpnow remain only as compatibility wrappers pointing at package-owned namespaced views - package-owned public-rendering support now includes
PageRouteResolver,PublicPagePresenter,PublicSharedSlotResolver,SlotWrapperResolver,SiteAssetResolver,PublicSearchQuery,PublicOverlayRegistry,PublicBodyEndRegistry,TrustedHtmlOverlayExtractor,SiteResolver,ResolvedSite, andVisitorEventLogger - root
App\Support\...classes for those public-rendering concerns were later removed once package internals and routes no longer required them - package
resources/views/pages/partials/blocks/*now owns the full shipped public block renderer partial tree as one coherent package batch - root
resources/views/pages/partials/blocks/files now remain as thin compatibility wrappers that delegate to matchingwebblocks-cms::pages.partials.blocks.views Block::publicRenderView()now resolves shipped core block types to package-owned namespaced block partials first, while install-specific or custom root block renderers still remain available through the existing root fallback path when no matching package partial exists- the public model foundation now lives under package
src/Models/; matching rootApp\Models\...wrappers were later removed after package/fresh-consumer tests proved they were unnecessary Page,PageTranslation,PageSlot, andBlocknow also live under packagesrc/Models/, without matching root wrappersUserremains app-owned and root-owned intentionally and is not part of the package model migration target- package
public/cms/now includes the active public runtime CSS and JS files needed by the moved package-owned public layout and block-rendering layer, andvendor:publish --tag=webblocks-cms-assetsnow publishes those real package assets into the rootpublic/cmscompatibility path - active runtime still serves
public/cms/...from the root install for compatibility, with install and System Update refreshing package-owned CMS assets into that path - root migrations remain authoritative for source-maintained checkouts with the explicit root Composer autoload signal, while package-native System Updates skip host Laravel application migrations and only run dedicated package update migrations when present
- System Update, install flow, backup or restore, and broader project-layer runtime remain unchanged in this batch
- consumer or starter-package validation is still not realistic after this checkpoint because the runtime still depends on root migrations, root compatibility asset paths, root-owned admin and install/update flows, and the intentionally app-owned root
Usermodel boundary
The current Site and Locale admin runtime checkpoint moves one more coherent admin slice behind the package-owned admin route tree:
- package-owned controllers now handle Site admin management, Site Domain management, Site Variable management, and Locale admin management under
packages/webblocks-cms/src/Http/Controllers/Admin/ - package-owned Form Requests,
SiteLocaleandSiteVariablemodels, and directly supporting Site or Locale support services now live under packagesrc/, without matching rootApp\...wrappers - package
resources/views/admin/sites/,resources/views/admin/sites/domains/,resources/views/admin/domains/, andresources/views/admin/locales/now own the active Site, Domain, and Locale admin Blade trees through thewebblocks-cms::namespace - root Site, Domain, and Locale Blade files now remain as thin compatibility wrappers that render the matching package-owned views
- this batch intentionally does not move migrations, installer/update flows, backup/restore, auth/profile/User ownership, root config ownership, or public/cms asset authority
Package-owned default config has now started for webblocks-updates, while the root config file still remains authoritative as the install override during the transition.
Package-owned default config has now also started for contact, while the root config file still remains authoritative as the install override during the transition.
Package-owned default config has now also started for demo_media, while the root config file still remains authoritative as the install override during the transition.
Package-owned default config has now also started for cms, while the root config file still remains authoritative as the install override during the transition.
Package-owned console bootstrap is now also proven through the read-only webblocks:package-status diagnostic command.
The package view namespace webblocks-cms is now also registered safely as a package-boundary pilot, and v1.31.63 now proves that namespace with a real package-owned diagnostic view. Active root view resolution still remains authoritative because no active CMS runtime admin or public views have been moved into the package.
The package route boundary is now also proven with a real package-owned diagnostic route file, but active root admin and public route resolution still remains authoritative because package diagnostic routes stay guard-disabled in normal runtime and no active root route files have been moved into the package.
The package migration, public asset, and stub boundaries are now also explicitly completed as inert reserved pilots, and the Composer-managed update-flow boundary is now documented as the target direction only. No active root migrations, root public assets, root stubs behavior, or root update flow behavior has moved into package authority yet.
The first package-owned PHP source move is now complete for SearchTextNormalizer, moved from app/Support/Search/ to package src/Support/Search/ with behavior kept unchanged.
The Search support boundary remains intentionally narrow in this phase: SearchTextNormalizer and the small result value object PublicSearchRebuildResult are now package-owned, while search indexing and query orchestration remain root-owned until their DB and runtime dependencies are migrated deliberately.
The first non-Search Support audit is also now documented: MediaKindResolver, DatabaseExecutionStrategyResolver, SiteHandle, and SiteDomainNormalizer were reviewed, and no additional class was moved because each still crosses at least one current early-phase risk boundary.
The first Contact support source move is now also complete for ContactMessageNotificationResult, moved from app/Support/Contact/ to package src/Support/Contact/ with behavior kept unchanged while the notifier service and contact runtime flow remain root-owned.
The first BlockTypes support source move is now also complete for BlockTypeContract, moved from app/Support/BlockTypes/ to package src/Support/BlockTypes/ with behavior kept unchanged while the registry, admin contract modal path, and audit command remain root-owned.
LayoutMarkup has also now been audited as a possible narrow Pages helper move and remains root-owned for now because its current references still cross page-layout request validation, admin form rendering, and public slot-wrapper behavior.
The first Formatting support source move is now also complete for InlineRichTextRenderer, moved from app/Support/Formatting/ to package src/Support/Formatting/ with behavior kept unchanged while SafeRichTextRenderer and its sanitization contract remain root-owned.
The next low-risk runtime support checkpoint is now also complete for four narrow helpers that stay close to admin query-state and pagination concerns:
AdminPaginationnow lives in packagesrc/Support/Admin/BlockTypeIndexStatenow lives in packagesrc/Support/BlockTypes/MediaIndexStatenow lives in packagesrc/Support/Media/PageIndexStatenow lives in packagesrc/Support/Pages/- root
App\Support\...wrappers for these helpers were later removed; package imports are authoritative
The first package-owned seeder boundary move is now also complete for low-risk catalogs:
- package-owned now:
IconCatalogSeeder,PageTypeSeeder,LayoutTypeSeeder,SlotTypeSeeder - package-owned now also:
CoreCatalogSeederas the catalog aggregator boundary move - root
Database\Seeders\...classes remain as compatibility wrappers CoreCatalogSeederstill keeps root entrypoints stable by delegating through the root wrapper while continuing to call root-ownedPageLayoutSeederandBlockTypeSeederPageLayoutSeeder,BlockTypeSeeder, and active System Update seeding remain root-owned until a later focused phase
The next isolated package-owned runtime batch is now also complete for icon catalog management:
- package-owned now:
SyncWebBlocksUiIconsCommand,IconCatalogController,IconCatalogItemUpdateRequest,IconCatalog, andWebBlocksIconManifestSyncer - root
App\Http\Controllers\Admin\IconCatalogController,App\Http\Requests\Admin\IconCatalogItemUpdateRequest,App\Support\Icons\..., andApp\Console\Commands\SyncWebBlocksUiIconsCommandwere later removed as redundant package-counterpart wrappers - active icon catalog admin routes now point directly at the package controller, and
icons:sync-webblocks-uiis now registered by the package service provider with the package command class - active icon catalog admin route definitions now live in package
routes/admin.phpinstead of rootroutes/web.php - root icon catalog PHP wrappers are no longer available; active route and console authority live in the package
- package-owned now also: the active icon catalog admin index and edit-modal Blade views under
packages/webblocks-cms/resources/views/admin/system/icons/ - root icon catalog Blade files remain as compatibility wrappers that include the package namespaced views, but the package controller renders
webblocks-cms::admin.system.icons.indexdirectly - this batch stays within the icon catalog admin and sync concern only and intentionally does not move broader Pages, Blocks, Search indexing, Sites, Updates, Install, Backup or Restore, Export or Import, or public rendering runtime ownership
webblocks:package-statusnow reports package-owned icon runtime files and the absence of matching root PHP wrappers as part of the read-only transition diagnostic
The next larger admin runtime extraction batch is now also complete for the core editorial and catalog management surfaces:
- package
routes/admin.phpis now authoritative not just for icon catalog management but also for the active Pages, Blocks, Media, Shared Slots, Navigation, Block Types, and Page Layouts admin route handlers - package-owned now: the authoritative admin controllers for those slices under
packages/webblocks-cms/src/Http/Controllers/Admin/ - package-owned now: the authoritative admin form requests for those slices under
packages/webblocks-cms/src/Http/Requests/Admin/ - package-owned now: the supporting block, media, navigation, page, page-layout, and shared-slot services under
packages/webblocks-cms/src/Support/ - package-owned now: the active admin Blade trees under
packages/webblocks-cms/resources/views/admin/blocks/,admin/media/,admin/navigation/,admin/block-types/,admin/pages/,admin/shared-slots/,admin/page-layouts/, andadmin/page-layout-slots/ - root
App\Http\Controllers\Admin\...,App\Http\Requests\Admin\..., andApp\Support\...PHP wrappers for those moved slices were later removed as redundant package-counterpart wrappers - root
resources/views/admin/...files for those moved trees now remain as compatibility wrappers that include the matchingwebblocks-cms::admin.*views - one exception intentionally remains concrete at the root:
resources/views/admin/blocks/types/partials/rich-text-editor.blade.phpstill keeps the real markup because compatibility coverage reads that root file directly instead of resolving it only through the package namespace - this batch intentionally does not move Users, backups, updates, system settings, install flow, migrations, root runtime asset paths, or the app-owned
Usermodel webblocks:package-statusplus focused bootstrap coverage now report the broader package-owned admin runtime files and that matching root PHP wrappers are absent
The focused operational admin runtime batch is now also package-owned:
- package-owned controllers now handle the Dashboard, Contact Messages admin review UI, Visitor Reports UI, and System Search status or rebuild UI under
packages/webblocks-cms/src/Http/Controllers/Admin/ - package-owned support now includes the visitor reporting query service and the lightweight public-search schema status helper; the full search indexing architecture and
search:rebuildcommand behavior remain unchanged behind root compatibility entrypoints - package
resources/views/admin/dashboard.blade.php,admin/contact-messages/*,admin/reports/visitors/index.blade.php, andadmin/system/search.blade.phpnow own the active operational admin Blade surfaces through thewebblocks-cms::namespace - root controller, support, and Blade files for those operational surfaces remain as thin compatibility wrappers
- this batch intentionally does not move System Update, System Backup, backup/restore, site export/import, site promotion, installer, auth/profile/User ownership, migrations, root config ownership, or root
public/cmsasset authority
The remaining safe live operational-route follow-up is now also complete:
- package-owned controllers now also handle
Slot TypesandSystem Settingsunderpackages/webblocks-cms/src/Http/Controllers/Admin/ - package-owned requests now also include
SystemSettingsRequestunderpackages/webblocks-cms/src/Http/Requests/Admin/ - package
resources/views/admin/slot-types/index.blade.phpandresources/views/admin/system/settings.blade.phpnow own the active Blade surfaces through thewebblocks-cms::namespace - root
App\Http\Controllers\Admin\SlotTypeController,App\Http\Controllers\Admin\SystemSettingsController,App\Http\Requests\Admin\SystemSettingsRequest, and the matching root Blade files remain as compatibility wrappers - this follow-up intentionally still does not move System Update implementation, backup or restore, installer, auth/profile/User ownership, migrations, root config ownership, or root
public/cmsruntime asset authority
The admin shell and asset boundary status is:
- package-owned admin views extend
webblocks-cms::layouts.admin, and the rootresources/views/layouts/admin.blade.phpcompatibility wrapper has been removed so package-consumer namespace mistakes fail locally - package
public/cms/also carries admin CSS and JS source files that match the active root admin asset set, while rootpublic/cms/...paths remain the live runtime compatibility layer - migrations, updater, backup/restore, export/import, promotion, auth/User, installer, root config, and runtime asset authority remain outside the immediate package admin-shell boundary
The selected shared admin partial/component batches are now package-owned:
- package-owned now:
webblocks-cms::admin.partials.page-header,flash,listing-filters,page-actions,pagination, andaudit-actor - package-owned now:
webblocks-cms::components.admin.form-actions, consumed from package views through<x-webblocks-cms::admin.form-actions> - package-owned now:
webblocks-cms::layouts.admin, consumed from package-owned admin views through@extends('webblocks-cms::layouts.admin', ...) - root
resources/views/admin/partials/{page-header,flash,listing-filters,page-actions,pagination,audit-actor}.blade.phpremain as compatibility wrappers - root
resources/views/layouts/admin.blade.phpno longer exists; plugin and package admin views must not use the historicallayouts.adminpath - root
resources/views/components/admin/form-actions.blade.phpremains as the compatibility wrapper for existing<x-admin.form-actions>usage - package-owned admin views now prefer the package namespace for the admin layout and those selected shared partials/components
webblocks:package-statusnow reports the selected shared admin partial/component boundary plus the admin runtime view inventory that now includes the package-owned admin layout and root wrapper- root admin asset URLs and runtime authority under
public/cms, brand assets, auth/profile/install/app/guest boundaries, migrations, updater, backup/restore, and release/version work remain unchanged
The v1.32.15 package boundary sweep adds a static release-gate audit for package-owned admin runtime references:
- the audit scans
packages/webblocks-cms/src/*/.php,packages/webblocks-cms/resources/views/*/.blade.php, andpackages/webblocks-cms/routes/*/.php - it fails on root-only admin references such as
view('admin.'),View::make('admin.'),response()->view('admin.'),@include('admin.'),@includeIf('admin.'),@extends('layouts.admin'),<x-admin.,<x-auth-password-field,component('admin.'), and directadmin.blocks.types.root block admin references - the only accepted exceptions are exact file-and-pattern allowlist entries where package runtime already checks the
webblocks-cms::...name first and uses the root name only as an explicit compatibility fallback for existing install-specific overrides
The initial low-risk helper and value-object source checkpoint is now considered successful and complete for this phase. The local development environment also updated successfully after v1.31.60, confirming that the current package wiring works in the maintained development environment.
Further opportunistic low-risk PHP source moves are now paused. Future runtime-heavy source moves require a dedicated focused phase plan and dependency audit instead of more small opportunistic migrations.
It does not yet move existing CMS runtime code, change System Update behavior, create a starter project, or change the current active runtime ownership boundaries.
Next Extraction Batch Plan
Step 1 moved active CMS route authority into the package for admin and public runtime, and it also moved the public route entry slice for page, search, contact-message, and privacy-consent requests. The next batch should reduce the largest remaining dual-ownership area behind that package route authority instead of starting another narrow pilot.
Current blocker map
Models still blocking independent package runtime:
- remain root-owned temporarily with documented package dependency: admin-content models such as
BlockType,Media,SharedSlot,PageAsset,PageLayout,PageRevision,NavigationItem,SiteExport, andSiteImport - package-owned with root compatibility wrappers:
Locale,Site,SiteDomain,SiteLocale,SiteVariable,Page,PageTranslation,PageSlot,Block,ContactMessage,PublicSearchIndex,VisitorEvent, andSystemSetting - likely package-ready soon as a narrow follow-up to an already-package-owned slice:
IconCatalogItem - should remain app-owned:
User
View boundaries still blocking independent package runtime:
- package public layout, page shell, search shell, search modal, slot-entry views, and shipped public block-renderer partial tree are now authoritative through the
webblocks-cms::namespace - root
resources/views/pages/partials/blocks/*remains intentionally present as a compatibility wrapper layer so install-specific root block renderers and direct root view references continue to work during the transition - package admin rendering is now authoritative for
admin/pages/,admin/blocks/,admin/shared-slots/,admin/media/,admin/navigation/,admin/block-types/,admin/page-layouts/,admin/page-layout-slots/,admin/sites/,admin/domains/, andadmin/locales/*through thewebblocks-cms::namespace, while matching root Blade files remain as compatibility wrappers - root admin rendering remains authoritative for the still-unmoved screens, especially install/auth/profile wrappers and app-owned user edge cases, while package rendering is authoritative for the active site transfer and promotion admin screens through
webblocks-cms::
Support and service boundaries still blocking independent package runtime:
- package-owned now for the public-rendering slice: route resolution, page presentation, shared-slot presentation, slot-wrapper resolution, trusted HTML overlay extraction, public overlay or body-end registries, public search query orchestration, public site resolution, site asset resolution, and visitor event logging
- move only after model moves: the remaining Pages or PublicRendering, Blocks, Search indexing, Navigation, SharedSlots or Revisions layers that still sit directly on root models or broader admin flows
- keep root-owned for now: Media, Sites portability flows, Formatting sanitization, Admin or Audit helpers
- should remain install-root-owned: Install, System or Updates, backup or restore, installed-version and environment writers
Requests, commands, assets, migrations, and update-flow blockers:
- many admin Form Requests can move later with root wrappers once the owning page, block, shared-slot, media, site, and navigation batches move
- many editorial admin Form Requests have now already moved with root wrappers, but system, site portability, update, backup, install, and other operations-oriented requests still remain root-owned
- package-used update, backup, import, export, promotion, and installer commands should remain explicitly bounded because they still depend on environment, filesystem, archive, Composer, migration, and install-state behavior
- root
public/cms/*assets remain the active authoritative runtime paths even though packagepublic/cms/now carries the moved public layout CSS and JS too and can publish them throughwebblocks-cms-assets - root migrations remain authoritative for source-maintained checkouts with maintenance-repository root Composer autoload authority; package-native fresh consumers installed with
webblocks:installmust not run host Laravel application migrations during System Update - WebBlocks UI Manager no longer ships inside the CMS package runtime. Its source lives under
plugins/webblocks-ui-managerfor maintenance builds, and operators install it manually as a plugin ZIP when they need WebBlocks UI release/CDN workflows. - Phase 5 plugin package readiness keeps plugin-owned classes, views, routes, commands, config, settings namespaces, and database prefixes attributable to plugin handles; disabled or incompatible plugins remain inert and do not become CMS core responsibilities
- package consumer System Updates only run dedicated package-owned update migrations from
vendor/fklavyenet/webblocks-cms/database/migrations/updateswhen present, and otherwise skip migration execution without marking arbitrary host migrations as run - System Update remains a separate phase because its blockers are environment mutation, filesystem writes, Composer execution, backups, migrations, installed-version persistence, and root operational state, not route or controller ownership
Consolidation outcome
- Safe CMS-owned source consolidation: complete
- Remaining moved helper inversion cleanup: complete (
WebBlocks\Cms\Support\Blocks\BlockTranslationWriterandCoreBlockTypeCatalogSyncernow own the implementation; rootApp\Support\Blocks\...classes remain only as compatibility wrappers) - Active runtime asset URL consolidation: intentionally incomplete; root
public/cms/...remains the compatibility runtime path - Starter split readiness: not ready
- Remaining final boundaries: install/auth/profile runtime, app-owned
User, root migration authority, root update/install authority, and the future starter split design
Recommended next batch
Recommended batch: do focused model/support compatibility cleanup for already package-owned runtime slices, or run the next admin asset and brand strategy pass now that the admin layout plus admin CSS or JS source files are package-owned. Keep active root public/cms admin asset authority in place until the admin asset strategy is explicit.
Scope completed in this checkpoint:
- public shell and page views:
layouts.public,pages.show,search.show, andsearch/partials/modal - page slot-entry rendering partials under
resources/views/pages/partials/slot*.blade.php - shipped public block renderer partials under
resources/views/pages/partials/blocks/* - the public rendering support layer for route resolution, public page presentation, shared-slot presentation, slot-wrapper resolution, trusted HTML overlay extraction, overlay registries, search query orchestration, site resolution, site asset resolution, and visitor event logging
- root compatibility wrappers where route, controller, request, or view references still need backward-compatible root entrypoints
Scope intentionally deferred from this batch:
- package-owned Eloquent model extraction for
Locale,Site,SiteDomain,Page,PageTranslation,PageSlot,Block,ContactMessage,PublicSearchIndex,VisitorEvent, andSystemSetting - authoritative package runtime asset URLs and publishing flow
- root migration authority redesign
- System Update and install/update flow extraction
Why this batch is next:
- package admin route, controller, request, support, and view authority now already exists across the major admin runtime slices
- the selected shared admin partials/components and their narrow edge cases have now moved, leaving larger shell/asset boundaries
- the package-owned admin layout plus package-owned admin CSS or JS source files still rely on active root runtime asset and brand loading, so the next step should be a deliberate admin asset and brand strategy rather than another shell move
- the next high-value extraction work is reducing remaining model/support compatibility assumptions or designing the admin asset/brand strategy without jumping into migrations, updater, backup/restore, export/import, promotion, auth/User, installer, root config, or asset authority
Large batches that should wait
- site portability batch: Export or Import plus Promotion should wait until their archive, backup, and transfer boundaries are explicitly audited
- migrations, active runtime assets, installer, backup/restore, auth/User, and System Update must remain separate dedicated phases
Alternative if shared partials reveal hidden coupling
Fallback batch: a focused remaining model/support compatibility cleanup for already package-owned runtime slices.
This is the fallback only if shared partials reveal unexpected auth, updater, backup, or install coupling that makes a thin root-wrapper pattern too noisy for a small implementation batch.