MyronCMS Developers Hub Docs sandbox review

Core Concepts

Extension Package Anatomy

An extension package is a local directory under app/extensions/{vendor}/. The vendor name is the package identity, the namespace root, and the prefix used by runtime registrations.

Extension v1 is intentionally local. A developer or AI coding agent authors files in the repository. A running MyronCMS install loads those files only after the operator registers the extension and grants the scopes it needs.

Package Shape

A typical package looks like this:

app/extensions/{vendor}/
  manifest.json
  bootstrap.php
  actions/
  admin/routes/
  migrations/
  README.md
PathCurrent statusPurpose
manifest.jsonStable currentDeclares vendor identity, name, version, requested base scopes, migration flag, and admin routes.
bootstrap.phpStable currentReturns runtime contributions for the loader to register.
actions/Stable currentHolds MyronAction classes registered under /api/v1/x/{vendor}/....
admin/routes/Stable currentHolds optional isolated admin route handlers declared in the manifest.
migrations/Stable currentHolds optional isolated migration files for {vendor}_* tables.
README.mdRecommendedDocuments the extension for humans and local AI agents.

The reference package is app/extensions/myron-sample/. It includes a manifest, bootstrap file, action, admin route, migration, and README.

Human Path

A developer creates the package files locally, then an operator registers the extension in the Extensions admin surface. The operator grants only the scopes needed by the extension.

The package must pass these basic checks:

  • the directory vendor normalizes to the manifest vendor,
  • the manifest parses,
  • required scopes are known base scopes,
  • registered actions stay under the extension URI and domain namespace,
  • migrations touch only {vendor}_* tables,
  • bootstrap failures are captured as extension load errors.

AI Path

An AI coding agent working in the repository may create or edit files under app/extensions/{vendor}/. That is local authoring.

An installed MCP client connected to a running MyronCMS install has a narrower runtime role. It may discover and call exposed tools after the extension is registered, enabled, granted scopes, loaded, and marked with exposeToMcp: true. It does not create PHP files, grant itself scopes, or bypass the loader.

Bootstrap Payload

bootstrap.php receives $sdk and $manifest in loader scope. The loader accepts:

  • a direct MyronAction,
  • a list of MyronAction instances,
  • an array with actions,
  • an array with micElementTypes,
  • an array with mailTransports.

Later guides cover MIC resolvers, mail transports, admin routes, and migrations in more depth. Core Concepts only defines how those package slots fit together.

Safety Boundary

Keep extension files and runtime contributions inside the extension namespace. Extension v1 does not support marketplace install, package dependency resolution, code signing, sandbox isolation, public render hooks, design token group registration, snapshot contribution, PHP event hooks, or core admin rail injection.

If an extension idea depends on one of those surfaces, do not work around the runtime. Start a new Evaluate and Contract cycle before changing platform behavior.

Verification

Use the foundation smoke test after authoring or changing extension package behavior:

php app/tests/verify-extension-system-foundation.php

That test verifies manifest parsing, namespace rejection, scope grants, loader behavior, sample action dispatch, migration isolation, load error capture, admin route mounting, and Extensions rail visibility.

Failure Modes

FailureWhere it surfaces
Directory and manifest vendor mismatchManifest parsing rejects the extension.
Unknown required scopeManifest parsing rejects the extension.
Extension not registeredLoader skips the extension.
Extension disabledLoader skips runtime registration.
Required scope not grantedLoader records an ungranted-scope failure.
Bootstrap throwsLoader records a load error and core requests continue.
Action URI or domain escapes namespaceAction registration rejects the action.
Migration touches a core tableMigration runner rejects the migration.