Problem/Motivation

The context/metadata system used usage_notes and schema_meta naming which was inconsistent and unclear. The hook_entity_blueprint_schema_meta_alter hook name didn't clearly convey its purpose, and the system lacked a declarative (non-PHP) way to provide context and managed keys — modules had to implement hooks even for purely static data.

The EntityStorageHandler lived in the entity_blueprint_ai sub-module despite being a general-purpose storage routing service, limiting reuse by other consumers of the base module.

Field handlers had no mechanism to advertise the input formats they accept, forcing AI consumers to rely on hardcoded documentation or system prompts to understand field type semantics.

There was no workspace enforcement — AI tools could persist content changes directly to the live environment without requiring an active workspace, creating risk of unreviewed changes in production.

The schema builder did not check entity access, allowing schema retrieval for bundles the current user cannot create. Layout components always required an explicit region even for single-region layouts, adding unnecessary verbosity for the most common case.

Proposed resolution

Context system refactor:

  • Rename usage_notes to guidance and hook_entity_blueprint_schema_meta_alter to hook_entity_blueprint_context_alter throughout.
  • Add YAML file discovery for both context (MODULE.entity_blueprint.context.yml) and managed keys (MODULE.entity_blueprint.managed_keys.yml), with scoped variants for entity_type/bundle-specific declarations (MODULE.entity_blueprint.context.ENTITY_TYPE.BUNDLE.yml).
  • Three-layer precedence: universal YAML → scoped YAML → hooks (alter always wins). Uses array_replace_recursive() for clean scalar replacement.
  • Add a field_types context level so modules can provide or override guidance per field type.

Field handler guidance:

  • Add getGuidance(): ?string to FieldHandlerInterface. All handlers implement it with concise LLM-facing descriptions of accepted input formats.
  • Guidance is collected by BlueprintSchemaBuilder into a deduplicated field_types section in schema output, and also included per-field in field info.

Workspace enforcement:

  • Move EntityStorageHandler from entity_blueprint_ai to the base entity_blueprint module as a proper service (entity_blueprint.storage_handler).
  • Add WorkspaceRequiredException and workspace checking to EntityStorageHandler::persist().
  • Add configurable require_workspace setting (default: TRUE) with admin form at /admin/config/content/entity-blueprint.
  • Add SettingsFormTrait for shared form elements, used by both the standalone SettingsForm and a SettingsFormAlter hook class that embeds settings in the Plus Suite form.
  • Add requireWorkspace() helper to EntityBlueprintToolBase — all AI write tools call it at the top of execute(). When a workspace is required, the tool returns available workspaces and instructs the AI to ask the user before choosing.
  • Add SwitchWorkspace AI tool plugin for switching to or creating workspaces.

Other improvements:

  • Schema builder now checks bundle create access before returning schema.
  • Single-region layouts no longer require explicit region on components — both the structural validator and layout deserializer auto-resolve the default region.
  • Add hook_entity_blueprint_entity_persisted to the base module (fires from EntityStorageHandler after every successful persist).
  • Rename the AI sub-module's persist hook to hook_entity_blueprint_ai_tool_persisted for clarity, and change its $save parameter to $is_new.
  • GenerateImage now routes through EntityStorageHandler::persist() instead of calling $media->save() directly.
  • Rename schema key layout_builder to layout_builder__layout to match the actual field name.
  • Remove unused workflow_hint from serializer output.
  • Reorder ALWAYS_SKIP_FIELDS and add entity_workflow_content to the skip list.

User interface changes

  • New admin settings form at /admin/config/content/entity-blueprint with a "Require workspace for content changes" checkbox (visible only when the Workspaces module is enabled).
  • Module now has a "Configure" link on the Extend page pointing to this settings form.
  • Entity Blueprint settings are also embedded in the Plus Suite settings form when that module is present.

API changes

  • Renamed hook: hook_entity_blueprint_schema_meta_alterhook_entity_blueprint_context_alter. Parameter renamed from $meta to $context.
  • Renamed key: usage_notesguidance in all schema output and context arrays.
  • Renamed schema key: layout_builderlayout_builder__layout in schema output.
  • New hook: hook_entity_blueprint_context_alter supports a field_types level for per-field-type guidance.
  • New hook: hook_entity_blueprint_entity_persisted in the base module (fires after EntityStorageHandler::persist()).
  • Renamed hook (AI sub-module): hook_entity_blueprint_entity_persistedhook_entity_blueprint_ai_tool_persisted with $save renamed to $is_new.
  • New interface method: FieldHandlerInterface::getGuidance(): ?string.
  • Moved service: entity_blueprint_ai.storage_handlerentity_blueprint.storage_handler (class moved from Drupal\entity_blueprint_ai to Drupal\entity_blueprint namespace).
  • New exception: WorkspaceRequiredException thrown by EntityStorageHandler::persist().
  • New AI tool plugin: entity_blueprint:switch_workspace (SwitchWorkspace).
  • YAML discovery: Modules can now declare managed keys and context via YAML files instead of hooks.
  • Schema builder now requires create access for the bundle; throws BlueprintException on access denied.
  • Region omission: Components in single-region layouts no longer require an explicit region.

Data model changes

New config object entity_blueprint.settings with a single require_workspace boolean property (default: TRUE).

Comments

tim bozeman created an issue. See original summary.

  • tim bozeman committed 09da4313 on 1.0.x
    feat: #3584815 Refactor context discovery system and add workspace...
tim bozeman’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.