Skip to content

[Server][Capability] Split RegistryInterface by role and defer loading into any registry - #686

Draft
chr-hertel wants to merge 2 commits into
mainfrom
issue-495-capability-element-sources
Draft

chr-hertel wants to merge 2 commits into
mainfrom
issue-495-capability-element-sources

Conversation

@chr-hertel

@chr-hertel chr-hertel commented Nov 8, 2026 •

Copy link
Copy Markdown
Member

Step 4 of #495: RegistryInterface now extends a catalog, a resolver and a writer role, and request handlers depend on the role they use. Existing implementations keep working.

setLazyLoading(true) now also defers loading into a registry from setRegistry(). The builder wraps it in an internal decorator instead of handing the registry a loader, so no Registry has to adopt one after construction - that was the objection on #494, happy to hear if this shape still has the same problem.

Capabilities are now detected when a request asks for them, since nothing reads them earlier - so the builder doesn't need to know what is loaded and a server advertises what it actually holds.

[BC Break] with that explicit call, a registry you read directly stays empty until the server first reads it. Without the call it still loads at build.

[BC Break] initialize, server/discover and subscriptions/listen run a pending load, so the handshake is no longer free of discovery. Configuration::$capabilities becomes capabilities().

Compared to #495, DeferredRegistryInterface has loadFrom() and isLoaded() instead of isEmpty().

@chr-hertel chr-hertel added the Server Issues & PRs related to the Server component label Nov 8, 2026
@chr-hertel chr-hertel added this to the 1.0.0 milestone Nov 8, 2026
@chr-hertel
chr-hertel requested a balanced review from Copilot November 8, 2026 13:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Capability detection can trigger a supplied registry’s loader during build() despite lazy loading, potentially freezing a cold source empty or failing the build.

1 open issue
What changed in this PR

This PR advances #495 by splitting registry responsibilities and adding opt-in deferred loading for caller-supplied registries, while preserving their default eager loading.

Changes:

  • Introduces catalog, resolver and writer interfaces, with request handlers depending on the role they use.
  • Adds a lazy registry decorator and a load-lifecycle interface for custom registries.
  • Adds regression tests and documents the loading behavior and compatibility change.
File Description
tests/​Unit/​Server/​BuilderTest.php Covers supplied-registry loading and capability detection.
tests/​Unit/​Capability/​Registry/​LazyRegistryTest.php Tests deferred loading, retries and event suppression.
src/​Server/​Stateless/​StandardHeaderValidator.php Depends on the resolver interface.
src/​Server/​Handler/​Request/​ResourceUnsubscribeHandler.php Depends on the resolver interface.
src/​Server/​Handler/​Request/​ResourceSubscribeHandler.php Depends on the resolver interface.
src/​Server/​Handler/​Request/​ReadResourceHandler.php Depends on the resolver interface.
src/​Server/​Handler/​Request/​ListToolsHandler.php Depends on the catalog interface.
src/​Server/​Handler/​Request/​ListResourceTemplatesHandler.php Depends on the catalog interface.
src/​Server/​Handler/​Request/​ListResourcesHandler.php Depends on the catalog interface.
src/​Server/​Handler/​Request/​ListPromptsHandler.php Depends on the catalog interface.
src/​Server/​Handler/​Request/​GetPromptHandler.php Depends on the resolver interface.
src/​Server/​Handler/​Request/​CompletionCompleteHandler.php Depends on the resolver interface.
src/​Server/​Handler/​Request/​CallToolHandler.php Depends on the resolver interface.
src/​Server/​Builder.php Wraps explicitly deferred custom registries and adjusts capability detection.
src/​Capability/​RegistryInterface.php Extends the three role interfaces.
src/​Capability/​Registry/​LazyRegistry.php Adds the deferred-loading decorator.
src/​Capability/​Registry.php Implements the load-lifecycle interface.
src/​Capability/​ElementWriterInterface.php Defines registration and removal operations.
src/​Capability/​ElementResolverInterface.php Defines individual element lookups.
src/​Capability/​ElementCatalogInterface.php Defines paginated element listings.
src/​Capability/​DeferredRegistryInterface.php Defines loading and event-suppression contracts.
docs/​run/​server-builder.md Documents custom-registry loading options.
CHANGELOG.md Records the new interfaces and compatibility change.

Review effort: Balanced

Comment thread src/Server/Builder.php Resolved
@chr-hertel
chr-hertel force-pushed the issue-495-capability-element-sources branch from 7105cab to f9cf392 Compare November 8, 2026 15:02
@chr-hertel
chr-hertel requested a balanced review from Copilot November 8, 2026 15:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved registry-loading defects can prevent retries after a failed concurrent load and trigger premature capability detection for third-party lazy registries.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment thread src/Server/Builder.php Resolved
@chr-hertel
chr-hertel force-pushed the issue-495-capability-element-sources branch 2 times, most recently from fa5a2d2 to a567732 Compare November 8, 2026 17:09
Comment thread src/Server/RegistryCapabilities.php Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Critical issues remain: capability-loading exceptions can escape request handling and terminate the stdio loop, while concurrent loading can incorrectly mark the decorator loaded and permanently lose registrations.

2 open issues
2 resolved since last review

Review effort: Balanced

@chr-hertel
chr-hertel force-pushed the issue-495-capability-element-sources branch from efe0366 to 176b86a Compare November 10, 2026 21:37

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Server Issues & PRs related to the Server component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants